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

Scrapy使用中间件替换重定向URL为原URL后无法正确发送请求如何解决

Scrapy 自定义重定向中间件实现方案

现有代码的核心问题

你设置了dont_redirect=True后,Scrapy 自带的RedirectMiddleware不会处理3xx响应,也不会自动填充request.meta['redirect_urls']字段,所以你现有逻辑中读取跳转地址的逻辑无法生效。同时你把429限流状态码和重定向状态码混合处理,逻辑不符合实际场景。

修改后的实现代码

from urllib.parse import urljoin

class CustomRedirectMiddleware:
    def process_request(self, request, spider):
        request.headers['User-Agent'] = self.ua.random

    def process_exception(self, request, exception, spider):
        return self._retry(request, spider)

    def _retry(self, request, spider, redirect_url=None):
        request.dont_filter = True
        # 有传入跳转地址则替换URL,否则重试原地址
        if redirect_url:
            redirected = request.replace(url=redirect_url)
            redirected.dont_filter = True
            # 保留原请求的所有meta参数
            redirected.meta.update(request.meta)
            return redirected
        return request

    def process_response(self, request, response, spider):
        # 处理重定向状态码
        if response.status in [301, 302, 307]:
            # 从响应头Location字段获取跳转地址,处理字节解码
            location = response.headers.get('Location', b'').decode('utf-8', errors='ignore')
            if not location:
                return response
            # 兼容相对路径跳转,拼接成绝对URL
            absolute_redirect_url = urljoin(response.url, location)
            # 传入跳转地址调用重试方法
            return self._retry(request, spider, redirect_url=absolute_redirect_url)
        # 处理429限流,直接重试原地址
        elif response.status == 429:
            return self._retry(request, spider)
        return response

配置说明

需要在项目settings.py中调整下载中间件优先级,确保你的自定义中间件在默认重定向、重试中间件之前执行,同时可以关闭默认重定向中间件避免冲突:

DOWNLOADER_MIDDLEWARES = {
    # 替换为你自己的中间件导入路径
    '你的项目名.middlewares.CustomRedirectMiddleware': 543,
    # 关闭默认重定向中间件
    'scrapy.downloadermiddlewares.redirect.RedirectMiddleware': None,
}

注意事项

  • 爬虫发起请求时携带的meta={'dont_redirect': True,"handle_httpstatus_list": [301,302,307,429]}配置不需要修改,保持即可
  • 如果需要限制重定向次数,可以在meta中新增自定义字段比如redirect_times,每次重定向时计数,超过阈值则放弃请求避免死循环

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 12:15:03