scrapy处理301/302重定向需禁用内置重定向中间件(redirect_enabled=false),并自定义downloader middleware在process_response中解析location头、保留callback和meta发起新请求,或在spider中手动拦截响应跳转。

当Scrapy爬虫请求目标URL后返回301或302状态码,却没拿到真实页面内容,而是跳转到了登录页、404页或移动端地址,说明重定向被默认中间件接管但未按需处理,导致数据提取逻辑失效或爬虫提前终止。
禁用内置重定向并启用自定义中间件
第一步:在项目根目录的 mymiddlewares.py 中创建重定向处理器:
```python
from scrapy import Request
class CustomRedirectMiddleware:
def process_response(self, request, response, spider):
if response.status in (301, 302, 307) and response.headers.get('Location'):
location = response.headers.get('Location').decode('utf-8')
# 强制保留原始 callback 和 meta,避免丢失解析上下文
return Request(
url=location,
callback=request.callback,
meta=request.meta,
dont_filter=True
)
return response
```
第二步:修改 settings.py,关闭默认重定向并注册新中间件:
```python
REDIRECT_ENABLED = False
DOWNLOADER_MIDDLEWARES = {
'myproject.mymiddlewares.CustomRedirectMiddleware': 543,
}
```
【myproject 必须替换成你实际的项目名,否则中间件不会加载】
不写中间件的快速应对方案
方法一:直接在 Spider 中拦截 302 响应
在 parse 方法开头加判断:
```python
def parse(self, response):
if response.status in (301, 302):
new_url = response.headers.get('Location').decode('utf-8')
yield scrapy.Request(new_url, callback=self.parse_detail, dont_filter=True)
return
# 后续正常解析逻辑
```
方法二:强制禁用重定向 + 手动检查 Location
发起请求时显式关闭自动跳转:
```python
yield scrapy.Request(
url='https://example.com/list',
callback=self.handle_redirect,
meta={'original_url': 'https://example.com/list'},
dont_filter=True
)
```
然后定义 handle_redirect 方法专门处理响应头:
```python
def handle_redirect(self, response):
if response.status in (301, 302) and response.headers.get('Location'):
loc = response.headers.get('Location').decode('utf-8')
if loc.startswith('//'):
loc = 'https:' + loc
yield scrapy.Request(loc, callback=self.parse_content)
else:
yield {'url': response.url, 'status': response.status}
```
绕过重定向陷阱的关键配置
有些网站对 User-Agent 或 Cookie 敏感,触发 302 跳转到 m.site 或 login 页面。此时仅处理状态码不够,必须同步补全请求特征:
在 settings.py 中设置:
```python
COOKIES_ENABLED = False
DEFAULT_REQUEST_HEADERS = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
'Referer': 'https://www.example.com/',
}
```
如果目标站校验 Referer 或需要会话态,【COOKIES_ENABLED = False 必须与 DEFAULT_REQUEST_HEADERS 中的 cookie 字段互斥,否则无效】











