python - 如何使用 Scrapy Python 从重定向链接中提取网站 URL
问题描述
我编写了一个脚本来从网站获取数据。我在收集网站 URL 时遇到问题,因为 @href 是重定向链接。如何将重定向 URL 转换为它重定向到的实际网站?
import scrapy
import logging
class AppSpider(scrapy.Spider):
name = 'app'
allowed_domains = ['www.houzz.in']
start_urls = ['https://www.houzz.in/professionals/searchDirectory?topicId=26721&query=Design-Build+Firms&location=Mumbai+City+District%2C+India&distance=100&sort=4']
def parse(self, response):
lists = response.xpath('//li[@class="hz-pro-search-results__item"]/div/div[@class="hz-pro-search-result__info"]/div/div/div/a')
for data in lists:
link = data.xpath('.//@href').get()
yield scrapy.Request(url=link, callback=self.parse_houses, meta={'Links': link})
next_page = response.xpath('(//a[@class="hz-pagination-link hz-pagination-link--next"])[1]/@href').extract_first()
if next_page:
yield response.follow(response.urljoin(next_page), callback=self.parse)
def parse_houses(self, response):
link = response.request.meta['Links']
firm_name = response.xpath('//div[@class="hz-profile-header__title"]/h1/text()').get()
name = response.xpath('//div[@class="profile-meta__val"]/text()').get()
phone = response.xpath('//div[@class="hz-profile-header__contact-info text-right mrm"]/a/span/text()').get()
website = response.xpath('(//div[@class="hz-profile-header__contact-info text-right mrm"]/a)[2]/@href').get()
yield {
'Links': link,
'Firm_name': firm_name,
'Name': name,
'Phone': phone,
'Website': website
}
解决方案
您必须向该目标 URL 发出请求才能查看它指向的位置
在您的情况下,您可以简单地执行HEAD
请求,该请求不会加载任何目标 URL 正文,这样可以节省带宽并提高脚本的速度
def parse_houses(self, response):
link = response.request.meta['Links']
firm_name = response.xpath('//div[@class="hz-profile-header__title"]/h1/text()').get()
name = response.xpath('//div[@class="profile-meta__val"]/text()').get()
phone = response.xpath('//div[@class="hz-profile-header__contact-info text-right mrm"]/a/span/text()').get()
website = response.xpath('(//div[@class="hz-profile-header__contact-info text-right mrm"]/a)[2]/@href').get()
yield Request(url=website,
method="HEAD",
callback=self.get_final_link,
meta={'data':
{
'Links': link,
'Firm_name': firm_name,
'Name': name,
'Phone': phone,
'Website': website
}
}
)
def get_final_link(self, response):
data = response.meta['data']
data['website'] = response.headers['Location']
yield data
如果您的目标是获取网站,那么每个列表的源代码中也提供了实际的网站链接,您可以通过正则表达式获取它,无需访问加密的 url
def parse_houses(self, response):
link = response.request.meta['Links']
firm_name = response.xpath('//div[@class="hz-profile-header__title"]/h1/text()').get()
name = response.xpath('//div[@class="profile-meta__val"]/text()').get()
phone = response.xpath('//div[@class="hz-profile-header__contact-info text-right mrm"]/a/span/text()').get()
website = re.findall(r"\"url\"\: \"(.*?)\"", response.text)[0]
推荐阅读
- android - Xamarin.Forms 使用 FFImageLoading 刷新图像 URI?
- maven - java.util.ServiceConfigurationError:org.apache.juli.logging.Log
- javascript - 读取并解析后从 JSON 文件中返回一个随机值
- javascript - 模糊背景,加载预加载图像时
- python-3.x - Debian:安装“python3-pip”后“pip3:找不到命令”
- sql - 查找源 S1 和 S2 之间 table1 行数的差异并更新 table2
- scrapy - scrapy 卡在调试中:Telnet 控制台正在侦听 127.0.0.1
- php - PHP - 作曲家自动加载 - 找不到类
- cluster-computing - SGE(Sun Grid Engine)如何监控作业的 VMEM(虚拟内存)使用情况?
- javascript - JavaScript 中对象数组的长度