乱码不是网页有问题,而是python将response.content解码为字符串时编码不匹配;应优先用response.content手动解码,按响应头→html meta→charset_normalizer顺序确定编码,避免依赖response.text。

乱码不是网页本身有问题,而是 Python 在把 response.content(原始字节)转成字符串时,用错了编码——关键卡在解码这一步,不是抓不到,是“读错了”。
为什么 response.text 一用就乱?
response.text 是 requests 自动调用 response.content.decode(response.encoding) 的结果,而 response.encoding 的推导顺序是:Content-Type 响应头 → HTML 中的 <meta> 标签 → chardet(或 charset_normalizer)粗略检测。任意一环出错(比如响应头写 charset=utf-8,实际发的是 gbk),response.text 就不可信;更关键的是:改完 response.encoding 后再读 .text,它也不会重解码,只会返回缓存值。
所以:永远优先用 response.content,别依赖 .text 首次访问前必须设好 response.encoding,设晚了无效
怎么安全地从 response.content 解码出正确字符串?
手动解码才可控,但不能瞎试。得按可信度降序取编码源:
- 先查响应头:
response.headers.get('content-type', ''),用正则提取charset=([^;]+) - 再查 HTML
<meta>:用re.search(rb'<meta>]*charset=[\'"]?([^\'">]+)', response.content[:10240]),只搜前 10KB 避免慢 - 最后 fallback 到
charset_normalizer(比chardet更准更快,尤其对中文):from charset_normalizer import from_bytes<br>r = from_bytes(response.content)<br>encoding = r[0].confidence > 0.7 and r[0].encoding or 'gb18030'
解码时务必加 errors='replace' 或 errors='ignore',防止个别坏字节崩掉整个解析。
保存文件还是乱码?那是另一回事
爬取乱码和写文件乱码是两件事:前者是读取时解错了,后者是 Python 写入时用了错误编码。
- 用
open(..., 'w')必须显式传encoding='utf-8',Python 默认编码不一定是 UTF-8 - 存 CSV 给 Excel 用,推荐加 BOM:
open(..., 'w', encoding='utf-8-sig') - 如果目标网站是老站(如新浪、网易体育),大概率是
gbk或gb2312,直接试response.content.decode('gbk', 'ignore')往往比猜更快
最易被忽略的点:response.apparent_encoding 是 requests 内置的 chardet 粗略检测,不准时别硬信;而 charset_normalizer 虽好,但它对极短响应(
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











