
当系统中安装了 zstandard 包时,requests 会自动在 Accept-Encoding 请求头中加入 zstd,导致部分服务返回未经解压的 zstd 压缩内容(如乱码字节流),而 requests 默认不支持解压 zstd —— 卸载 zstandard 是最直接、安全且无需修改大量代码的解决方案。
当系统中安装了 zstandard 包时,requests 会自动在 accept-encoding 请求头中加入 zstd,导致部分服务返回未经解压的 zstd 压缩内容(如乱码字节流),而 requests 默认不支持解压 zstd —— 卸载 zstandard 是最直接、安全且无需修改大量代码的解决方案。
在 DSM 7 等嵌入式或轻量级 Python 环境中,requests 库的行为可能因依赖包的存在而悄然改变。典型表现是:原本正常返回 HTML 或 JSON 的 requests.get(url).content 突然返回一长串不可读的二进制数据(如以 \xb5/\xfd\x04X... 开头),调试后发现请求头中多出了 zstd 编码支持:
Accept-Encoding: gzip, deflate, br, zstd
⚠️ 关键事实:
-
requests本身不内置 zstd 解压缩能力; - 仅当第三方包
zstandard被安装时,requests(通过底层urllib3)才会自动启用zstd编码协商; - 但若目标服务器返回了
Content-Encoding: zstd响应,而requests无法解压,就会将原始压缩字节原样暴露给.content—— 这正是你看到“奇怪编码数据”的根本原因。
✅ 推荐解决方案(零代码修改):
直接卸载触发该行为的依赖包:
pip uninstall zstandard
执行后,requests 将恢复默认的 Accept-Encoding: gzip, deflate, br,不再协商 zstd,所有现有脚本可立即恢复正常运行。
? 替代方案(不推荐,仅作了解):
若因其他依赖必须保留 zstandard,可通过全局禁用 zstd 协商(需 monkey patch,稳定性差):
import requests.adapters
from urllib3.util import parse_url
# 强制移除 zstd(不推荐用于生产)
original_make_headers = requests.adapters.HTTPAdapter._get_default_headers
def patched_headers(self):
headers = original_make_headers(self)
enc = headers.get('Accept-Encoding', '')
headers['Accept-Encoding'] = ', '.join(
e.strip() for e in enc.split(',') if e.strip() != 'zstd'
)
return headers
requests.adapters.HTTPAdapter._get_default_headers = patched_headers
但此方式易受 requests 版本更新影响,且无法覆盖 Session 实例级自定义头,远不如卸载 zstandard 简洁可靠。
? 注意事项:
-
zstandard是高性能压缩库,仅在明确需要 zstd 编解码(如处理 Kafka 消息、ZSTD 日志归档等)时才应安装; - 普通 Web 爬虫、API 调用、自动化脚本完全不需要它;
- 卸载后可通过
pip list | grep zstandard验证是否已清除; - 若使用虚拟环境,请确保在对应环境中执行
pip uninstall,避免影响其他项目。
总之,这不是 requests 的 bug,而是其按设计与生态包协同工作的结果。理解「功能启用依赖于可选依赖存在」这一机制,能帮你更稳健地管理 Python 网络请求行为。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











