You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

重写start_requests后Scrapy爬虫无法爬取起始URL外页面求助

问题分析与解决方案

你遇到的问题核心有两点:

  1. 重写start_requests时直接指定callback=parse_item,跳过了CrawlSpider内置的parse方法,导致定义的Rules链接提取规则完全失效,爬虫只会处理起始URL,不会跟进其他页面。
  2. 即便Rules生效,LinkExtractor生成的后续请求也不会自动携带起始URL元数据,需要手动传递。

修改后的完整代码

from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from scrapy.http import Request

class TSpider(CrawlSpider):
    name = 't'
    allowed_domains = ['books.toscrape.com']  # 修正原域名拼写错误,多了一个"s"
    start_urls = ['https://books.toscrape.com']

    # 自定义请求处理方法,传递起始URL元数据
    def pass_start_url(self, request, response):
        request.meta['start_url'] = response.meta['start_url']
        return request

    rules = (
        Rule(LinkExtractor(allow=[r'.*page.*']), 
             callback='parse_item', 
             follow=True,
             process_request='pass_start_url'),  # 绑定元数据传递方法
    )

    def start_requests(self):
        for url in self.start_urls:
            # 起始请求回调用CrawlSpider默认的parse方法,触发Rules生效
            yield Request(url, callback=self.parse, meta={'start_url': url})

    def parse_item(self, response):
        item = {}
        item['title'] = response.xpath('//head/title/text()').get()  # get()更适合提取单个文本节点
        item['url'] = response.url
        item['start_url'] = response.meta['start_url']
        yield item

关键修改说明

  • 修正域名错误:原代码allowed_domains写成了books.toscrapes.com,多了一个s,会导致后续请求被爬虫过滤。
  • 恢复Rules触发逻辑:起始请求的callback改为self.parse,这是CrawlSpider处理Rules的入口方法,能自动执行链接提取和跟进逻辑。
  • 传递元数据:通过Rule的process_request参数绑定自定义方法pass_start_url,将起始URL从响应的meta中传递给新生成的请求,确保所有页面的请求都携带start_url元数据。
  • 优化数据提取:把extract()改为get(),更简洁地提取单个文本节点结果。

内容的提问来源于stack exchange,提问作者John M.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 15:01:56