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

Scrapy结合Splash时返回Splash服务端响应头而非目标站点头如何解决

Scrapy + Splash 获取目标站点原始响应头方案

问题原因

Splash是独立的渲染代理服务,你向Splash服务发起请求时,response.headers默认返回的是Splash服务本身的HTTP响应头,目标站点的原始响应头存储在Splash返回的结构化元数据中,不会自动覆盖到Scrapy的响应头字段。

解决方案

方案1:手动从HAR数据中提取

Splash支持返回HAR(HTTP归档)格式的请求记录,里面包含了渲染过程中所有网络请求的完整信息,包括目标站点的响应头,提取步骤如下:

  1. 构造SplashRequest时开启HAR记录参数:
from scrapy_splash import SplashRequest

yield SplashRequest(
    url="目标站点URL",
    callback=self.parse,
    args={
        "har": 1, # 开启HAR记录
        "html": 1, # 同时返回渲染后的HTML,不影响正常页面解析
    }
)
  1. 回调函数中提取目标响应头:
def parse(self, response):
    # 读取HAR数据
    har_data = response.data["har"]
    # 默认第一条entry为目标站点主页面请求,有重定向场景可调整为最后一条
    main_request_entry = har_data["log"]["entries"][0]
    # 提取原始响应头
    target_headers = {
        header["name"]: header["value"] 
        for header in main_request_entry["response"]["headers"]
    }
    
    # 测试打印
    print(target_headers)
    # 后续可正常解析页面内容

方案2:自定义中间件自动替换响应头

如果需要全局使用目标站点的响应头,可自定义下载中间件自动替换Splash的服务响应头:

  1. 新建自定义中间件:
class TargetHeaderReplaceMiddleware:
    def process_response(self, request, response, spider):
        # 仅处理带HAR数据的Splash响应
        if hasattr(response, "data") and "har" in response.data:
            try:
                entry = response.data["har"]["log"]["entries"][0]
                # 转换为Scrapy响应头的bytes格式
                response.headers = {
                    h["name"].encode(): [h["value"].encode()] 
                    for h in entry["response"]["headers"]
                }
            except (KeyError, IndexError):
                # 提取失败时保留原有响应头,不影响正常请求
                pass
        return response
  1. 在settings.py中注册中间件,优先级需高于默认的压缩中间件、低于Splash核心中间件:
DOWNLOADER_MIDDLEWARES = {
    'scrapy_splash.SplashCookiesMiddleware': 723,
    'scrapy_splash.SplashMiddleware': 725,
    # 替换为你自己项目的中间件路径
    '你的项目名称.middlewares.TargetHeaderReplaceMiddleware': 726,
    'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810,
}

配置完成后,直接调用response.headers即可获取目标站点的原始响应头。

注意事项

  • 如果目标站点存在301/302重定向,需调整entry的取值,取HAR记录中最后一个对应目标域名的请求条目即可
  • 需保证Splash服务版本在2.0以上,低版本存在HAR字段返回不全的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 21:45:00