使用Python requests访问需前置页面解锁的站点被拦截如何解决?
问题原因
你当前的代码被拦截核心是因为网站反爬策略除了校验IP、User-Agent、Cookie外,还会校验请求头完整性、跳转来源、动态校验参数、TLS指纹、请求协议版本等维度,requests默认配置和真实浏览器请求特征差异过大,很容易被识别。
可落地解决方案
1. 补全请求基础校验项
- 补全完整请求头:不要只配置
User-Agent,需要把Accept、Accept-Language、Accept-Encoding、Sec-Fetch-*等浏览器默认携带的头全部补全,和真实浏览器请求头完全一致。 - 增加
Referer校验头:请求URL2时必须在请求头中增加Referer: URL1,大部分网站会校验第二个页面的跳转来源。 - 检查Session携带Cookie有效性:请求完URL1后打印
s.cookies.get_dict()确认URL1返回的所有Cookie都被Session正常存储,部分分路径的Cookie可以手动添加到URL2的请求头中。 - 提取页面动态参数:部分网站会在URL1的响应页面中嵌入
csrf token、session校验串等动态参数,需要用正则或者BeautifulSoup从URL1的返回内容中提取该参数,请求URL2时携带。
2. 绕过协议/指纹类拦截
如果上述配置调整后仍被拦截,可按优先级尝试以下方案,速度和requests接近,远快于Selenium:
- 适配HTTP/2协议:部分网站仅支持HTTP/2,且会拦截HTTP/1.1的请求,可替换requests为
httpx库,开启http2=True即可适配HTTP/2协议,用法和requests基本一致。 - 绕过TLS指纹检测:绝大多数反爬会校验JA3/JA3TLS指纹,requests默认指纹特征明显易被识别,可替换requests为
curl_cffi库,可直接模拟Chrome、Edge等浏览器的TLS指纹,用法和requests几乎完全一致,仅需在请求时增加impersonate参数指定模拟的浏览器版本即可。
修改后参考代码
import time from bs4 import BeautifulSoup # 普通场景用httpx,需要过TLS指纹用下面的curl_cffi导入 # import httpx from curl_cffi import requests proxies = { 'https' : "你的代理地址" } # 补全和浏览器一致的完整请求头 headers = { 'user-agent': '你的真实User-Agent', '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.9,en;q=0.8', 'Accept-Encoding': 'gzip, deflate, br', 'Connection': 'keep-alive', 'Upgrade-Insecure-Requests': '1', } # httpx初始化示例 # s = httpx.Client(http2=True, proxies=proxies, headers=headers) # curl_cffi初始化示例 s = requests.Session(proxies=proxies, headers=headers) # 请求URL1,模拟chrome110指纹 glos = s.get("URL1", impersonate="chrome110") # 确认Cookie校验 print("URL1返回Cookie:", s.cookies.get_dict()) # 示例:提取页面动态csrf参数 # soup = BeautifulSoup(glos.text, 'lxml') # csrf = soup.find('input', {'name': 'csrf_token'})['value'] # 请求URL2时携带即可 # 增加Referer头 headers['Referer'] = "URL1" time.sleep(5) # 请求URL2 r = s.get("URL2", headers=headers, impersonate="chrome110") print(r.text)
内容的提问来源于stack exchange,提问作者user16838936
相关产品推荐
相关产品推荐

