使用Python requests调用NCBI API时出现ChunkedEncodingError如何解决?
问题分析与解决思路
这个ChunkedEncodingError(具体为InvalidChunkLength)本质是HTTP分块传输环节出了问题:要么是服务器返回的分块长度无效,要么是连接中途被异常断开。从你描述的情况来看,大概率不是你的脚本逻辑错误——毕竟Postman和新脚本都能正常请求,只有原脚本偶尔触发该问题。
原脚本触发问题的可能原因
- 连接复用异常:如果原脚本使用了
requests.Session()复用TCP连接,之前的连接可能已被服务器端关闭,但客户端仍在复用,导致后续请求出错。而新脚本每次都是新建请求,用的是全新连接,因此不受影响。 - 请求头缺失:Postman会自动添加
User-Agent、Accept等标准请求头,原脚本可能头信息不全,服务器对这类“不完整”请求的处理不稳定。 - 触发限流机制:原脚本可能短时间内发送了大量请求,触发了NCBI E-utilities的限流规则,服务器主动中断了连接。Postman是单次请求,未达到限流阈值。
- 网络环境差异:原脚本所在环境的代理、防火墙或网络波动,偶尔导致连接中途断开,而Postman/新脚本使用的是更稳定的网络环境。
可行的解决办法
- 禁用连接复用:在请求中添加
Connection: close头,强制每次请求结束后关闭连接,避免复用无效连接:
response2 = requests.get( "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=mesh&id=" + str(id), headers={"Connection": "close"} )
- 补充标准请求头:模拟Postman的请求头格式,让请求更符合服务器的预期:
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", "Accept": "*/*" } response2 = requests.get( "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=mesh&id=" + str(id), headers=headers )
- 添加重试机制:针对偶发异常,捕获错误后自动重试:
import requests from requests.exceptions import ChunkedEncodingError def fetch_mesh_data(id): url = f"https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=mesh&id={str(id)}" max_retries = 3 for _ in range(max_retries): try: response = requests.get(url, headers={"Connection": "close"}) response.raise_for_status() return response.text except ChunkedEncodingError: continue raise Exception(f"请求失败,已重试{max_retries}次")
- 控制请求频率:NCBI E-utilities要求每秒最多3次请求,若原脚本请求过于频繁,需添加延迟(如
time.sleep(0.3)),避免触发限流。
内容的提问来源于stack exchange,提问作者Hannes
相关产品推荐
相关产品推荐

