Scrapy:如何实现中间件向爬虫本体传递捕获的请求数据
实现方案
完全可以通过自定义下载中间件实现原始请求头、请求体的捕获,这种方式拿到的是请求实际发出前的原始数据,比从response.request上取的准确性更高,不会被请求发送后的中间件处理逻辑篡改。
核心实现逻辑
- 选择下载中间件的
process_request方法作为捕获点:这个方法执行时请求还未发送到网络,此时拿到的request.headers、request.body就是最终发出的原始请求头和请求payload,不会经过响应阶段的逻辑修改。 - 捕获后的数据通过
request.meta传递即可,传递前注意把headers、body这类特殊类型转成常规可序列化格式,方便后续存库或者解析。 - 不要在捕获逻辑里修改请求本身的属性,避免影响正常请求发送。
中间件代码示例
from scrapy import Request import json from urllib.parse import parse_qs class RawRequestCaptureMiddleware: def process_request(self, request, spider): # 转换原始请求头为普通字典,统一处理字节编码 raw_headers = {} for key, value in request.headers.items(): raw_headers[key.decode("utf-8")] = value.decode("utf-8") # 捕获原始请求体,兼容不同请求格式做可读化解析 raw_body = request.body raw_body_parsed = raw_body content_type = raw_headers.get("Content-Type", "") try: if "application/json" in content_type: raw_body_parsed = json.loads(raw_body.decode("utf-8")) elif "application/x-www-form-urlencoded" in content_type: raw_body_parsed = {k: v[0] if len(v) ==1 else v for k,v in parse_qs(raw_body.decode("utf-8")).items()} else: raw_body_parsed = raw_body.decode("utf-8", errors="ignore") except: pass # 写入meta传递给后续爬虫逻辑 request.meta["raw_request_trace"] = { "request_url": request.url, "request_method": request.method, "headers": raw_headers, "raw_body": raw_body, "parsed_body": raw_body_parsed } # 无返回值,让请求继续走正常发送流程 return None
中间件配置
在项目settings.py中注册中间件,优先级调整到靠近下载器的位置,确保捕获的是最终发出的请求数据:
DOWNLOADER_MIDDLEWARES = { "your_project.middlewares.RawRequestCaptureMiddleware": 649, }
优先级数值越大越靠近下载器,650是Scrapy内置HttpCompressionMiddleware的优先级,设为649可以确保在所有请求修改类中间件执行完后、请求发送前捕获数据。
爬虫侧调用方式
在爬虫的解析方法中,直接从response.meta中读取捕获的数据即可,拿到的数据可以直接用于存库追踪:
def parse(self, response): trace_info = response.meta.get("raw_request_trace", {}) # 此处可直接把trace_info和爬取结果绑定存入数据库 yield { "item_content": ..., "request_trace": trace_info }
注意事项
- 遇到请求重试、重定向场景时,
process_request会在每次实际发请求前重新执行,捕获到的是和当前响应直接绑定的那次请求的原始数据,完全符合追踪需求。 - 如果存在大文件上传、大体积请求体的场景,可以在捕获逻辑里加判断,只存关键参数或者body摘要,避免meta占用过多内存。
- 可以按需加过滤规则,比如只捕获指定域名、指定路径的请求信息,减少不必要的性能开销。
内容的提问来源于stack exchange,提问作者fobik35911
相关产品推荐
相关产品推荐

