使用Python requests和urllib访问特定URL时遇ConnectionResetError
ConnectionResetError 问题排查与解决
常见原因
- TLS协议版本不兼容:服务器可能只支持特定TLS版本,requests默认配置不匹配,导致连接被强制关闭。
- 缺失关键请求信息:浏览器访问时会自动携带Cookie、会话标识等参数,你的请求缺少这些内容,被服务器拦截。
- 连接复用机制冲突:
keep-alive配置与服务器的连接策略不兼容,引发连接重置。 - IP触发反爬限制:频繁请求可能被服务器判定为爬虫,临时封禁IP(浏览器能访问是因为有缓存或已建立的会话)。
解决方案
1. 指定TLS版本
强制使用TLS 1.2或1.3适配服务器要求,通过自定义适配器实现:
import requests from requests.adapters import HTTPAdapter from urllib3.poolmanager import PoolManager import ssl class TLSAdapter(HTTPAdapter): def init_poolmanager(self, connections, maxsize, block=False): self.poolmanager = PoolManager( num_pools=connections, maxsize=maxsize, block=block, ssl_version=ssl.PROTOCOL_TLSv1_2 # 若无效可替换为ssl.PROTOCOL_TLSv1_3 ) headers = { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', 'Accept-Language': 'en-US,en;q=0.9', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive', 'DNT': '1', 'Pragma': 'no-cache', 'Sec-Fetch-Dest': 'document', 'Sec-Fetch-Mode': 'navigate', 'Sec-Fetch-Site': 'none', 'Sec-Fetch-User': '?1', 'Upgrade-Insecure-Requests': '1', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36', 'sec-ch-ua': '"Google Chrome";v="123", "Not:A-Brand";v="8", "Chromium";v="123"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': '"Windows"', } session = requests.Session() session.mount('https://', TLSAdapter()) try: response = session.get('https://newjersey.mylicense.com/verification/Search.aspx', headers=headers) print(response.status_code) except Exception as e: print(e)
2. 复制浏览器完整请求头
打开浏览器开发者工具(F12)→ Network标签,刷新页面后找到对应请求,复制包含Cookie在内的全部请求头,替换到代码中。服务器可能依赖Cookie验证会话合法性。
3. 禁用连接复用
取消keep-alive设置,避免连接复用引发的冲突:
headers.pop('Connection') # 移除keep-alive请求头 # 或通过会话禁用 session = requests.Session() session.keep_alive = False response = session.get('https://newjersey.mylicense.com/verification/Search.aspx', headers=headers)
4. 添加请求延迟与重试
模拟正常用户访问频率,避免触发反爬:
import time from requests.adapters import HTTPAdapter from urllib3.util.retry import Retry session = requests.Session() # 配置重试策略 retry_strategy = Retry( total=3, backoff_factor=1, # 重试间隔依次为1s、2s、4s status_forcelist=[429, 500, 502, 503, 504], ) adapter = HTTPAdapter(max_retries=retry_strategy) session.mount('https://', adapter) time.sleep(2) # 请求前等待2秒 response = session.get('https://newjersey.mylicense.com/verification/Search.aspx', headers=headers)
5. 排查本地网络
关闭本地代理、防火墙或杀毒软件,尝试切换网络(如手机热点),确认是否是本地环境拦截了请求。
内容的提问来源于stack exchange,提问作者chandandanjo
相关产品推荐
相关产品推荐

