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

Scrapy结合Splash发起爬取请求返回空字符串问题咨询

问题修复方案

爬取返回空是三个核心问题导致的,按下面的步骤改就能拿到数据:

  • 错误的请求头配置:你代码里写的headers是浏览器加载图片资源时用的请求头,accept字段声明要拿图片资源、sec-fetch-dest标记请求目标是图片、referer指向CSS文件路径,还带了Splash无法正确处理的HTTP/2伪头:authority,网站会直接把请求判定为异常,不会返回正常的菜谱页面HTML。
  • XPath选择器逻辑错误:目标页面的菜谱名称存放在class包含text-center的div下嵌套的h1标签内,你直接取div的直接文本节点,自然拿不到值。
  • 页面等待逻辑不可靠:只设置固定10秒等待,若页面JS渲染速度波动,核心内容还没挂载到DOM树Splash就返回源码,也会导致选择器匹配不到内容。

具体修改步骤
  1. 先确认settings.py配置正确,除了scrapy-splash官方文档的1-5步配置,补充核对以下内容:
SPLASH_URL = 'http://localhost:8050' # 确保本地Splash服务正常启动,端口匹配
DOWNLOADER_MIDDLEWARES = {
    'scrapy_splash.SplashCookiesMiddleware': 723,
    'scrapy_splash.SplashMiddleware': 725,
    'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810,
}
SPIDER_MIDDLEWARES = {
    'scrapy_splash.SplashDeduplicateArgsMiddleware': 100,
}
DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter'
HTTPCACHE_STORAGE = 'scrapy_splash.SplashAwareFSCacheStorage'
# 配置正常的浏览器UA,不要用版本过旧的Chrome79,容易被反爬识别
USER_AGENT = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
  1. 替换爬虫代码,去掉错误的自定义请求头,改用Lua脚本控制Splash等待指定元素加载完成后再返回源码,同时修正XPath:
import scrapy
from scrapy_splash import SplashRequest

class CookingSpider(scrapy.Spider):
    name = 'cooking'
    # Lua脚本:等菜谱名的h1标签加载完成再返回页面,比固定等待效率更高更稳定
    lua_render = """
    function main(splash, args)
        splash:set_user_agent(args.ua)
        assert(splash:go(args.url))
        splash:wait_for_selector('h1', 10)
        return splash:html()
    end
    """

    def start_requests(self):
        url = 'https://akispetretzikis.com/en/recipe/6641/patates-twn-15-wrwn'
        yield SplashRequest(
            url=url,
            callback=self.parse,
            endpoint='execute',
            args={
                'lua_source': self.lua_render,
                'ua': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
            }
        )

    def parse(self, response):
        yield {
            "name": response.xpath('//div[contains(@class, "text-center")]/h1/text()').get(default='').strip()
        }

排查提示
  • 运行爬虫前必须先启动Splash服务,本地部署直接执行命令docker run -p 8050:8050 scrapinghub/splash即可。
  • 如果调整后还是拿不到数据,先在parse方法里加with open('test.html', 'w', encoding='utf-8') as f: f.write(response.text)把返回的源码存到本地,看是返回了反爬拦截页、403页面还是空白页,再对应调整参数,不要盲目写选择器。
  • 不要直接复制浏览器开发者工具里的全量请求头,尤其是带资源类型标记、HTTP/2伪头的字段,很容易触发反爬。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 08:00:58