使用urllib.request.urlopen调用树莓派RESTful API时返回Content-Length为0
解决urllib.request调用REST API返回Content-Length 0的问题
看起来你碰到的这个问题挺常见的:浏览器端的REST客户端能正常拿到响应,但用Python的urllib库调用就返回空内容。这种情况大多是请求头差异或者urllib默认行为和浏览器不一致导致的,下面给你几个排查和解决的方向:
1. 模拟浏览器的请求头
YARC这类浏览器扩展会自动添加符合浏览器规范的请求头(比如User-Agent、Accept),而urllib默认的请求头比较简单,可能被服务器识别为非浏览器请求,从而返回空响应。
你可以手动构造请求头,模拟浏览器的请求,代码示例如下:
import urllib.request import json target_url = "http://1.2.3.4/yamaha/volume/relative/up/1/" # 复制YARC里的请求头(至少包含User-Agent和Accept,可从YARC的请求头面板直接复制) custom_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", "Accept": "application/json, text/plain, */*" } # 构造带请求头的Request对象 request = urllib.request.Request(target_url, headers=custom_headers) try: with urllib.request.urlopen(request) as response: # 先检查响应状态码,确认请求是否成功 print(f"响应状态码: {response.getcode()}") # 读取并解码响应内容 response_content = response.read().decode("utf-8") if response_content: result = json.loads(response_content) print("解析后的JSON响应:", result) else: print("仍然收到空响应,需要进一步排查") except Exception as e: print(f"请求异常: {str(e)}")
2. 检查重定向情况
有些服务器会对请求做重定向,YARC会自动处理重定向,但urllib的urlopen默认只处理GET/HEAD的重定向。你可以先禁用重定向,看看是否是重定向导致的空响应:
request = urllib.request.Request(target_url, headers=custom_headers) request.allow_redirects = False with urllib.request.urlopen(request) as response: print(f"状态码: {response.getcode()}") print(f"重定向地址: {response.getheader('Location')}")
如果返回3xx状态码,说明有重定向,你可以手动处理该地址的请求,或者确认urllib的重定向逻辑是否正常工作。
3. 对比curl和urllib的请求差异
用curl命令模拟请求,对比和urllib的请求头、响应内容:
curl -v http://1.2.3.4/yamaha/volume/relative/up/1/
查看curl的请求头和完整响应,再和urllib的请求头对比,找出缺失的关键头信息,补充到urllib的请求中。
4. 调整连接超时设置
响应头里有Keep-Alive配置,urllib默认的连接超时可能和服务器不匹配,你可以手动设置超时时间:
with urllib.request.urlopen(request, timeout=10) as response: # 处理响应逻辑
一般来说,模拟浏览器的请求头就能解决大部分这类问题,你可以先试试第一个方案,看看是否能拿到正常的JSON响应。
内容的提问来源于stack exchange,提问作者Eric D'Souza
相关产品推荐
相关产品推荐

