解决urllib3请求返回403问题:与requests请求结果对齐
问题:urllib3代理请求返回403,requests相同配置却返回200
我用requests通过代理请求目标网站能正常返回状态码200,但改用urllib3实现相同逻辑时,请求返回403。需求是让urllib3请求也能获得200的成功响应。
requests 可正常运行的代码
import requests proxies = {"http":"http://username:password@host:port"} #proxy protocol r = requests.get('https://www.examples.com', proxies=proxies) #make the request print(r.status_code) #return status code 200, successful request
urllib3 返回403的代码
import urllib3 auth_headers = urllib3.make_headers(proxy_basic_auth='username:password') #proxy authorization build Proxy = urllib3.ProxyManager(proxy_url="http://host:port", proxy_headers=auth_headers) url = 'https://www.example.com/' r = Proxy.request('GET', url) #make the request print(r.status) #return status code 403, I want it to return status code 200 like the same as the requests code.
补充说明:不使用代理(直接用PoolManager())时,urllib3请求可正常工作。
解决方案
1. 修正URL拼写差异
注意到requests请求的是https://www.examples.com,而urllib3请求的是https://www.example.com/(前者多一个s,后者末尾多斜杠),目标网站可能对URL路径敏感,先统一URL为相同地址。
2. 添加浏览器请求头(User-Agent)
requests默认会添加类似Mozilla/5.0的浏览器标识头,而urllib3默认的User-Agent是urllib3/x.y.z,部分网站会拦截这种非浏览器请求。手动添加请求头模拟浏览器:
import urllib3 auth_headers = urllib3.make_headers(proxy_basic_auth='username:password') # 模拟Chrome浏览器的User-Agent request_headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' } Proxy = urllib3.ProxyManager(proxy_url="http://host:port", proxy_headers=auth_headers) url = 'https://www.examples.com' # 统一URL r = Proxy.request('GET', url, headers=request_headers) print(r.status)
3. 对齐requests的代理配置写法
requests直接将用户名密码嵌入代理URL,urllib3也可以采用相同方式,避免头信息处理差异:
import urllib3 # 直接把用户名密码放在代理URL里,和requests写法一致 Proxy = urllib3.ProxyManager(proxy_url="http://username:password@host:port") url = 'https://www.examples.com' r = Proxy.request('GET', url, headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'}) print(r.status)
4. 临时禁用证书验证(仅调试用)
如果目标网站证书存在问题,requests默认的验证逻辑可能在特定环境下被跳过,urllib3可以临时关闭验证调试:
import urllib3 Proxy = urllib3.ProxyManager( proxy_url="http://username:password@host:port", cert_reqs='CERT_NONE' ) # 关闭不安全请求的警告 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) url = 'https://www.examples.com' r = Proxy.request('GET', url, headers={'User-Agent': 'Mozilla/5.0 ...'}) print(r.status)
内容的提问来源于stack exchange,提问作者spark
相关产品推荐
相关产品推荐

