Scrapy CrawlSpider跳转网站下一页时如何调用rules规则元组
问题原因
- CrawlSpider的
rules规则仅在响应交给框架内置的parse方法处理时才会触发匹配,你当前手动构造下一页请求时指定了callback=self.parse_item,响应会直接进入详情页处理逻辑,跳过了规则匹配,所以不会触发你定义的详情页提取规则。 - 现有逻辑存在重复请求风险:你把翻页逻辑写在
parse_item(详情页处理函数)中,每爬取1个详情页就会生成1次下一页请求,最终会产生大量重复的列表页请求。
调整后完整代码
from urllib import parse import scrapy from scrapy.linkextractors import LinkExtractor from scrapy.spiders import CrawlSpider, Rule class DetailsSpider(CrawlSpider): name = 'details' # 移除无用的首页地址,初始请求直接指向搜索结果列表页 start_urls = ['https://www.insiderpages.com/search/search?query=doctors&location=San+Francisco%2C+CA&commit=Go%21'] rules = ( Rule(LinkExtractor(restrict_xpaths=("//h2[@class='pixel-tracking']/a")), callback='parse_item', follow=True), ) def start_requests(self): for url in self.start_urls: # 初始请求交给内置parse方法处理,触发规则匹配 yield scrapy.Request(url, meta={"x": 1}, callback=self.parse) def parse_start_url(self, response): # 翻页逻辑统一放在列表页处理流程中,避免重复生成请求 x = int(response.meta['x']) if x != 10: next_url = f"https://www.insiderpages.com/s/CA/SanFrancisco/Doctors?cs_category=Doctors&page={x}&radius=0" # 下一页请求依旧交给内置parse处理,自动触发规则匹配 yield scrapy.Request(url=next_url, callback=self.parse, meta={"x": x+1}) def parse_item(self, response): yield{ 'Title':response.xpath("//h1[@class='org fn business_card_name name']/span/text()").get(), 'Address':response.xpath("//span[@class='adr address']/p/span/text()").get(), 'City':response.xpath("//span[@class='adr address']/p[2]/span/text()").get(), 'State':response.xpath("//span[@class='adr address']/p[2]/span[2]/text()").get(), 'Postal Code':response.xpath("//span[@class='adr address']/p[2]/span[3]/text()").get(), 'Phone':response.xpath("//li[@class='telephone']/strong/p/text()").get(), 'Email':response.xpath("//li[@class='email']/a/@href").get(), }
修改说明
- 把翻页逻辑从详情页处理函数中剥离,统一放到列表页处理流程中,避免生成大量重复请求
- 所有列表页请求的回调指定为CrawlSpider内置的
self.parse方法,响应返回后会自动触发rules规则匹配,提取页面内所有详情页链接并交给parse_item处理 - 调整了meta中页码参数的类型为整数,减少类型转换的冗余操作
内容的提问来源于stack exchange,提问作者Knight
相关产品推荐
相关产品推荐

