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

Scrapy爬虫可爬取单分类页面但无法爬取同分类下一页的问题求助

问题分析与解决方案

嘿,看了你的报错信息和代码,问题其实一目了然:你在请求下一页的时候,没有把category_name和Category_link这两个参数传递给info_parse方法,导致方法执行时缺少必填的位置参数,直接抛出了TypeError。

下面一步步给你解决问题,顺便优化下爬虫的效率:

1. 先搞定下一页的参数传递

你在parse方法里第一次调用info_parse时,用cb_kwargs传了参数,但处理下一页的时候只写了yield response.follow(url=final_url,callback=self.info_parse),完全没传那俩参数,这就是报错的根源。

把下一页的请求代码改成这样:

yield response.follow(
    url=final_url,
    callback=self.info_parse,
    cb_kwargs={'category_name': category_name, 'Category_link': Category_link}
)

另外,其实你手动拼接下一页URL的逻辑完全可以简化——Scrapy的response.follow会自动基于当前页面的URL处理相对路径,直接传next_page就行,不用手动拆分拼接,省得出错:

# 替换你原来的下一页URL拼接逻辑
next_page = response.xpath('//*[@class="next"]/a/@href').get()
if next_page:
    yield response.follow(
        next_page,
        callback=self.info_parse,
        cb_kwargs={'category_name': category_name, 'Category_link': Category_link}
    )

2. 优化书籍详情页的请求方式(非常重要!)

你现在在info_parse里用requests.get同步请求书籍详情页,这会彻底破坏Scrapy的异步并发机制,爬虫速度会慢得离谱,还容易被网站检测到反爬。

建议把书籍详情页的解析抽成单独的方法,用Scrapy的异步请求来处理:

def info_parse(self, response, category_name, Category_link):
    book_urls = response.xpath('//section/div/ol/li/article[@class="product_pod"]/h3/a/@href')
    for book_url in book_urls:
        book_info_url = response.urljoin(book_url.get())
        # 用Scrapy异步请求代替requests同步请求
        yield response.follow(
            book_info_url,
            callback=self.parse_book_detail,
            cb_kwargs={
                'category_name': category_name,
                'Category_link': Category_link,
                'Bookurl': book_info_url
            }
        )
    # 下一页逻辑(已修复)
    next_page = response.xpath('//*[@class="next"]/a/@href').get()
    if next_page:
        yield response.follow(
            next_page,
            callback=self.info_parse,
            cb_kwargs={'category_name': category_name, 'Category_link': Category_link}
        )

# 新增书籍详情解析方法
def parse_book_detail(self, response, category_name, Category_link, Bookurl):
    bookprize = response.xpath('//p[@class="price_color"]/text()').get()
    yield {
        'Category_Name': category_name,
        'Category_link': Category_link,
        'Bookurl': Bookurl,
        'Bookprize': bookprize
    }

3. 额外的小修复

你代码里的"应该是转义错误,实际写代码时直接用双引号"就行,避免语法问题。

完整的修复后代码

import scrapy
from ..items import ScrapybooksspiderItem

class ScrapSpider(scrapy.Spider):
    name = 'scrapp'
    allowed_domains = ['books.toscrape.com']
    start_urls = ['http://books.toscrape.com/']

    def parse(self, response):
        # 定位Historical Fiction分类
        categ = response.xpath('//div[@class="side_categories"]/ul[@class="nav nav-list"]/li/ul/li')
        category_name = categ.xpath('.//a[contains(text(),"Historical Fiction")]/text()').get().replace('\n', "").strip()
        category_link = categ.xpath('.//a[contains(text(),"Historical Fiction")]/@href').get().replace('\n', "").strip()
        
        yield response.follow(
            category_link,
            callback=self.info_parse,
            cb_kwargs={'category_name': category_name, 'Category_link': category_link}
        )

    def info_parse(self, response, category_name, Category_link):
        book_urls = response.xpath('//section/div/ol/li/article[@class="product_pod"]/h3/a/@href')
        for book_url in book_urls:
            book_info_url = response.urljoin(book_url.get())
            yield response.follow(
                book_info_url,
                callback=self.parse_book_detail,
                cb_kwargs={
                    'category_name': category_name,
                    'Category_link': Category_link,
                    'Bookurl': book_info_url
                }
            )
        
        # 处理下一页
        next_page = response.xpath('//*[@class="next"]/a/@href').get()
        if next_page:
            yield response.follow(
                next_page,
                callback=self.info_parse,
                cb_kwargs={'category_name': category_name, 'Category_link': Category_link}
            )

    def parse_book_detail(self, response, category_name, Category_link, Bookurl):
        book_prize = response.xpath('//p[@class="price_color"]/text()').get()
        yield {
            'Category_Name': category_name,
            'Category_link': Category_link,
            'Bookurl': Bookurl,
            'Bookprize': book_prize
        }

这样修改后,爬虫就能正常爬取下一页内容,同时保持Scrapy的异步高效性,不会再出现参数缺失的错误啦。

内容的提问来源于stack exchange,提问作者Abu Bakar Siddique

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 15:28:11