调试Python网络程序的核心是看清实际请求与响应,需用requests-toolbelt打印原始报文、mitmproxy抓包验证、先检查status_code和encoding、并用curl -v对照请求细节。
调试Python网络程序时,核心是看清“实际发了什么请求、收到什么响应”,而不是只看代码逻辑。重点不在框架或库本身,而在能快速捕获、解析、比对HTTP流量。
requests 默认不暴露原始 HTTP 报文(如带换行和头的完整请求),但调试时往往需要确认是否加了 header、body 是否被编码、URL 是否被错误拼接。requests-toolbelt 提供 PrintLoggingAdapter 或更直接的 dump_all 工具:
pip install requests-toolbelt
from requests_toolbelt.utils import dump
res = requests.get("https://httpbin.org/get", params={"q": "test"})
print(dump.dump_all(res).decode("utf-8"))
本地开发时,服务端还没上线,或依赖第三方 API 但返回异常——这时仅靠 print 或日志不够。mitmproxy 是轻量可控的中间人代理,能真实拦截 Python 程序发出的所有 HTTP/HTTPS 请求:
mitmproxy --mode reverse:https://httpbin.org(反向代理到目标站)proxies={"http": "http://127.0.0.1:8080", "https": "http://127.0.0.1:8080"}
会出现在 mitmproxy 界面中,可查看 raw request/response、重放、修改再发、导出 cURL很多“解析失败”其实不是 JSON 或 HTML 问题,而是状态码非 2xx 却直接 .json(),或响应用了非 UTF-8 编码但没显式指定:
if res.status_code != 200: print(res.status_code, res.reason, res.text[:200])
res.json() 自动解码:它默认用 res.encoding,而该值可能为 None 或错误(如服务器返回 GBK 编码但声明 UTF-8)res.content.decode("utf-8")(手动控制解码)或 res.apparent_encoding(chardet 推测,适合 HTML)当 Python 请求和 curl 结果不一致(比如登录失败、返回 403),最有效的方式不是改 headers 字段名,而是让 Python 发出和 curl 完全一样的请求:
curl -v -X POST "https://..." -H "User-Agent: ..." -d '{"a":1}' 记录完整请求报文requests.Request 手动构建,再用 session.prepare_request() 获取 PreparedRequest 对象,调用 .method/.url/.headers/.body 逐项比对