requests.get()返回的response.text常乱码,因encoding默认取响应头content-type,未声明或写错时fallback为iso-8859-1;应优先用response.content手动decode,保存时显式指定encoding='utf-8'等。

requests.get() 返回的 response.text 为什么经常乱码?
因为 response.text 会按 response.encoding 解码,而这个值默认来自响应头的 Content-Type;很多网站压根不写 charset,或写错(比如声明 utf-8 却发 GBK 字节),requests 就 fallback 成 ISO-8859-1,一解中文就变 。
实操建议:
- 永远优先用
response.content(原始字节)做后续处理,别碰.text - 手动 decode:比如
html = response.content.decode('utf-8', errors='ignore'),errors='ignore'比'replace'更适合保内容完整(尤其含 JS 字符串时) - 想自动猜编码?装
chardet:import chardet; encoding = chardet.detect(response.content)['encoding'] or 'utf-8',再 decode
保存时用 open(..., 'w') 报错 UnicodeEncodeError 怎么办?
Windows 默认用 cp1252 编码写文件,遇到中文直接崩;Linux/macOS 虽常默认 utf-8,但不显式声明仍可能出问题。
实操建议:
-
必须在
open()里写死encoding='utf-8',例如:with open('page.html', 'w', encoding='utf-8') as f: - 别信编辑器自动识别——它可能把乱码文件当 UTF-8 打开,显示一堆问号,实际是保存时就错了
- 如果目标网页本身用 GBK,decode 用
'gbk',write 也得用encoding='gbk',否则二次打开还是乱
用 BeautifulSoup 处理后再保存,为啥打开没样式、没脚本?
BeautifulSoup 默认解析后只保留“语义结构”,<script></script>、<style></style>、HTML 注释、甚至某些空格和换行都会被丢弃或重排,导致本地双击打开后页面功能异常、样式错位。
实操建议:
- 如果目标是「完整保存原始 HTML」,跳过 BS——直接存
response.content或修复编码后的字符串 - 非要用 BS 提取某块内容再保存(比如只存
#article_content),初始化时加参数:soup = BeautifulSoup(html, 'lxml', preserve_whitespace_tags=['script', 'style']) - 写回时别用
soup.prettify(),它会重排标签顺序;改用soup.encode('utf-8').decode('utf-8')或直接soup.__str__()
要不要用 requests-html 或 selenium?
requests-html 内置 Chromium,能执行 JS 渲染,但它启动慢、内存高、对 headless 模式反爬更敏感;selenium 更重,且默认不保存原始 HTML 的完整结构(比如动态插入的 <link rel="stylesheet"> 可能没加载完就被截了)。
实操建议:
- 先用浏览器开发者工具看 Network → HTML 请求,确认目标内容是否在初始响应里——是,就纯用
requests+ 正确编码处理 - 如果是 AJAX 加载的数据,直接抓 XHR 接口 URL,比渲染整个页面快得多、稳得多
- 真要等 JS 执行,优先选
playwright(比 selenium 更现代,API 更干净),且记得用page.content()获取完整 HTML,不是page.inner_html('body')
<link href="/css/main.css">)在本地打开时全部 404**。这不是编码问题,而是你保存的只是 HTML 文本,没下载对应 CSS/JS/图片。要“完整”到能离线查看,就得额外实现资源下载+路径重写——那已经是另一个层级的问题了。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











