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

Scrapy Playwright后续请求未触发,parse_next函数未调用求助

问题:Scrapy Playwright爬虫中parse_next函数未执行

我编写了如下Scrapy Playwright示例代码:

import json

import scrapy
import scrapy_playwright
from scrapy.selector import Selector
from scrapy_playwright.handler import Page, PageMethod


class GreetingsSpider(scrapy.Spider):
    name = "greetings"
    allowed_domains = ["example.com"]

    custom_settings = {
        "LOG_LEVEL": "INFO",
    }

    def start_requests(self):
        url = "https://www.example.com"
        yield scrapy.Request(
            url,
            callback=self.parse,
            meta={"playwright": True, "playwright_include_page": True},
        )


    async def parse(self, response):
        print("Hello ")
        page: Page = response.meta["playwright_page"]
        await page.close()
        print("Hello from parse next")
        yield scrapy.Request(
            response.url,
            callback=self.parse_next,
            meta={"playwright": True},
            errback=self.errback_close_page,
        )
        print("Hello from second parse next")
        

    def parse_next(self, response):
        print(response.url)

运行代码后,parse_next函数从未被调用,print(response.url)始终未执行。程序输出日志如下:

Hello 
Hello from parse next
Hello from second parse next
2022-11-03 07:26:03 [scrapy.core.engine] INFO: Closing spider (finished)
2022-11-03 07:26:03 [scrapy.statscollectors] INFO: Dumping Scrapy stats:
{'downloader/request_bytes': 193,
 'downloader/request_count': 1,
 'downloader/request_method_count/GET': 1,
 'downloader/response_bytes': 260537,
...
}
2022-11-03 07:26:03 [scrapy.core.engine] INFO: Spider closed (finished)
2022-11-03 07:26:03 [scrapy-playwright] INFO: Closing download handler
2022-11-03 07:26:03 [scrapy-playwright] INFO: Closing download handler
2022-11-03 07:26:03 [scrapy-playwright] INFO: Closing browser

日志显示仅发起1次请求爬虫就结束了,查阅官方文档后仍未找到问题所在,求分析解决。


解决办法

问题出在异步parse函数的处理逻辑以及Scrapy Playwright的配置缺失上,具体原因和修复步骤如下:

1. 缺少Scrapy Playwright必要配置

你的爬虫未启用Scrapy Playwright的下载中间件和处理器,导致第二个请求的meta={"playwright": True}无法生效,请求未被正确处理。需要在custom_settings中添加以下配置:

custom_settings = {
    "LOG_LEVEL": "INFO",
    "DOWNLOAD_HANDLERS": {
        "http": "scrapy_playwright.handler.ScrapyPlaywrightDownloadHandler",
        "https": "scrapy_playwright.handler.ScrapyPlaywrightDownloadHandler",
    },
    "DOWNLOADER_MIDDLEWARES": {
        "scrapy_playwright.middleware.PlaywrightMiddleware": 543,
    },
}

2. 未定义errback函数

你在第二个请求中指定了errback=self.errback_close_page,但未实现该函数,会导致请求出错被丢弃。需要补充该函数:

async def errback_close_page(self, failure):
    page = failure.request.meta.get("playwright_page")
    if page:
        await page.close()

3. 重复请求被过滤

第二个请求和第一个请求URL相同,Scrapy默认会过滤重复请求。需要在第二个请求中添加dont_filter=True参数,避免被过滤:

yield scrapy.Request(
    response.url,
    callback=self.parse_next,
    meta={"playwright": True},
    errback=self.errback_close_page,
    dont_filter=True  # 新增参数
)

修复后的完整代码

import json

import scrapy
import scrapy_playwright
from scrapy.selector import Selector
from scrapy_playwright.handler import Page, PageMethod


class GreetingsSpider(scrapy.Spider):
    name = "greetings"
    allowed_domains = ["example.com"]

    custom_settings = {
        "LOG_LEVEL": "INFO",
        "DOWNLOAD_HANDLERS": {
            "http": "scrapy_playwright.handler.ScrapyPlaywrightDownloadHandler",
            "https": "scrapy_playwright.handler.ScrapyPlaywrightDownloadHandler",
        },
        "DOWNLOADER_MIDDLEWARES": {
            "scrapy_playwright.middleware.PlaywrightMiddleware": 543,
        },
    }

    def start_requests(self):
        url = "https://www.example.com"
        yield scrapy.Request(
            url,
            callback=self.parse,
            meta={"playwright": True, "playwright_include_page": True},
        )

    async def parse(self, response):
        print("Hello ")
        page: Page = response.meta["playwright_page"]
        await page.close()
        print("Hello from parse next")
        yield scrapy.Request(
            response.url,
            callback=self.parse_next,
            meta={"playwright": True},
            errback=self.errback_close_page,
            dont_filter=True
        )
        print("Hello from second parse next")

    def parse_next(self, response):
        print(response.url)

    async def errback_close_page(self, failure):
        page = failure.request.meta.get("playwright_page")
        if page:
            await page.close()

运行修复后的代码,parse_next函数会被正常调用,日志中会显示第二次请求的记录,print(response.url)也会输出对应内容。


内容的提问来源于stack exchange,提问作者asfand hikmat

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 08:30:35