如何配置Python requests使其正确跟随302临时重定向
requests未跟随302重定向的解决方案
核心问题点
- requests默认仅对
GET/HEAD/OPTIONS请求自动开启重定向跟随,你当前使用requests.post()发起请求,默认不会自动跟随302重定向。 - 你在请求头中添加的
Access-Control-*系列字段属于服务端返回给浏览器的CORS响应头,客户端发送请求时携带这些字段属于无效内容,极易触发目标站点的反爬规则,导致重定向流程异常。 - 你访问的搜索结果页本身是GET类型接口,使用POST方法请求本身不符合接口的请求规范,会导致服务端返回非预期的响应。
- 原代码存在两个逻辑bug:一是使用了未提前定义的
sku变量,运行时会直接报错;二是重定向状态码判断逻辑写反,3xx区间的状态码才代表重定向,小于300是正常响应。
配置方法
- 对于GET类请求,requests默认已经开启自动重定向,无需额外配置;如果使用POST/PUT/DELETE等其他请求方法,需要在请求方法中显式传入参数
allow_redirects=True开启重定向跟随。 - 移除请求头中所有无效的
Access-Control-*字段,补充浏览器真实会携带的Accept、Accept-Language等字段,降低被反爬拦截的概率。 - 可通过
timeout参数设置请求超时时间,通过max_redirects参数设置最大重定向次数,避免无限重定向死循环。
修正后的可运行代码
import random import requests from pprint import pprint from bs4 import BeautifulSoup sku = '11343654' url = f'https://www.zurrose.de/catalogsearch/result?q={sku}' # 仅保留真实浏览器请求会携带的头字段,移除无效CORS头 headers = { 'Referer': 'https://www.zurrose.de', 'Connection': 'keep-alive', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8', 'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3' } user_agents = [ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:100.0) Gecko/20100101 Firefox/100.0', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.67 Safari/537.36' ] headers['User-Agent'] = random.choice(user_agents) # 改用匹配接口类型的GET方法,显式开启重定向跟随,设置超时 r = requests.get(url, headers=headers, allow_redirects=True, timeout=15) print('start') if r.history: print("请求被重定向") print(f"重定向链路: {r.history}") for resp in r.history: print(f"重定向状态码: {resp.status_code}, 跳转前地址: {resp.url}") print(f"最终目标地址: {r.status_code} {r.url}") else: print(f'地址{url}无重定向,状态码{r.status_code},SKU{sku}对应商品页未找到') soup = BeautifulSoup(r.content, 'html.parser') for i in soup.select('link[rel*=canonical]'): url_pp = i['href'] print(f"找到规范地址: {url_pp}") pprint(r.content)
补充说明:不同3xx重定向状态码的处理逻辑存在差异:303状态码会强制将原POST请求转为GET请求跳转,307/308状态码会保留原请求方法和请求体跳转,只要配置了
allow_redirects=True,requests会自动按照HTTP规范完成对应跳转逻辑,无需额外处理。
内容的提问来源于stack exchange,提问作者merlin
相关产品推荐
相关产品推荐

