lxml.html.fromstring遇非法utf-8字节会静默替换为而非报错,导致dom内容损坏;应先显式decode并指定errors策略(如ignore或replace),或按实际编码(如gbk)解码。

lxml.html.fromstring 遇到非法 UTF-8 字节会静默截断或替换,不是报错
当你把含非法字节(比如 0xFF 0xFE、截断的 UTF-8 多字节序列)的原始 bytes 直接喂给 lxml.html.fromstring(),它不会抛 UnicodeDecodeError,而是默认用 errors='replace' 策略解码 —— 把每个非法字节替换成 符号。结果是 DOM 树能建起来,但文本内容已损坏,XPath 查不到你预期的关键词。
真正该做的是:先显式 decode,控制错误处理行为:
- 用
html_bytes.decode('utf-8', errors='ignore')彻底丢弃非法字节(适合纯文本提取场景) - 用
html_bytes.decode('utf-8', errors='replace')保留结构但标记异常(适合需定位问题位置的调试) - 若原始网页大概率是 GBK,直接用
html_bytes.decode('gbk', errors='replace'),比依赖自动探测更可靠
DOMParser.parseFromString 对二进制数据直接返回空 Document
DOMParser.parseFromString() 只接受字符串,不接受 ArrayBuffer 或 Uint8Array。如果你把 raw bytes 当成 string 传进去(例如 parser.parseFromString(new Uint8Array([0xFF, 0xFE]).toString(), 'text/html')),结果一定是 document.documentElement === null,且无任何提示。
正确路径只有两条:
- 前端:先用
new TextDecoder('utf-8', {fatal: false})解码,fatal: false才允许跳过非法字节 - Node.js:用
Buffer.from(rawBytes).toString('utf8'),它内部等价于decode('utf8', 'replace')
gumbo-parser 能吞掉无效字节但不修复编码声明
gumbo-parser 的 C 层解析器本身对输入 bytes 是“宽容”的:遇到无法解析的 UTF-8 序列时,它会跳过并继续,不会 crash。但它完全不读取 HTML 中的 <meta charset="gb2312">
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











