urllib.request.urlopen访问地址报错10061但requests.get可正常获取数据
问题原因分析
核心原因是urllib.request和requests的默认代理策略不同,其次还有请求头默认配置的差异:
- urllib.request默认会自动读取并使用Windows系统的全局代理配置、系统环境变量中的HTTP_PROXY/HTTPS_PROXY配置,如果你的代理规则没有将
acm.aliyun.com这类内网域名、8080端口纳入直连名单,访问流量会被错误转发到代理服务器,代理无法访问对应内网地址就会返回连接被拒绝的10061错误。 - requests库默认不会主动读取系统全局代理,只有当你主动传入proxies参数、或者配置了REQUESTS_PROXY专属环境变量时才会走代理,所以可以直接和目标内网地址建立连接,访问正常。
- 次要原因是urllib.request默认发送的User-Agent为
Python-urllib/[版本号],部分服务会拦截这类特征明显的爬虫请求,不过这类场景一般返回403状态码,和你遇到的10061错误不符。
解决方法
可以通过以下方式修复urllib.request的访问报错:
- 强制urllib跳过系统代理,使用空代理配置:
import urllib from urllib.request import Request, urlopen, ProxyHandler, build_opener # 初始化空代理处理器,不使用任何代理 proxy_handler = ProxyHandler({}) opener = build_opener(proxy_handler) # 将自定义opener设置为全局生效 urllib.request.install_opener(opener) url = "http://acm.aliyun.com:8080/diamond-server/diamond" response = urllib.request.urlopen(url)
- 若修改代理后仍有问题,可添加模拟浏览器的请求头,避免被服务端拦截:
import urllib from urllib.request import Request, urlopen, ProxyHandler, build_opener proxy_handler = ProxyHandler({}) opener = build_opener(proxy_handler) urllib.request.install_opener(opener) url = "http://acm.aliyun.com:8080/diamond-server/diamond" # 构造带自定义请求头的Request对象 req = Request( url, headers={ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" } ) response = urlopen(req)
- 也可以直接修改系统代理配置,将
acm.aliyun.com、127.0.0.1、本地网段等内网地址加入代理直连名单,不需要修改代码即可正常访问。
内容的提问来源于stack exchange,提问作者chen
相关产品推荐
相关产品推荐

