直接用json.loads()解析HTML中嵌入的JSON字符串会报错,根本原因是双引号、&、

直接用 json.loads() 解析 HTML 里嵌的 JSON 字符串会报错
常见现象是:拿到一段 HTML 片段,里面藏着类似 {"name": "张三", "desc": "热销&爆款"} 这样的字符串,直接 json.loads() 就抛 JSONDecodeError: Invalid \escape 或者 Expecting property name enclosed in double quotes。根本原因不是 JSON 写错了,而是双引号、&、 等字符被 HTML 实体编码过,变成了 "、&、、<code>> —— 它们不是合法 JSON 的组成部分。
必须先 html.unescape() 再 json.loads()
这是最轻量、最稳妥的解法,不需要正则、不依赖第三方库,Python 标准库自带:
-
html.unescape()能正确还原所有标准 HTML 实体(包括{这类数字实体) - 还原后得到的是纯字符串,再交给
json.loads()就能正常解析 - 注意:不能颠倒顺序——先
json.loads()必然失败;也不能只替换几个实体(比如只 replace"),漏掉&或'仍会出错
示例代码:
import json
import html
<p>raw_html_str = '"{"name": "张三", "tag": "热销&爆款"}"'</p><h1>第一步:去掉 HTML 转义</h1><p>unescaped = html.unescape(raw_html_str)</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill9972" title="Wechat Article Html"><img
src="https://img.php.cn/upload/skill/001/246/273/6adaf20e695c2374.jpg" alt="Wechat Article Html" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill9972" title="Wechat Article Html" class="overflowclass">Wechat Article Html</a>
<p class="overflowclass">将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。</p>
</div>
<a rel="nofollow" href="/xiazai/skill9972" title="Wechat Article Html" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div><h1>第二步:真正解析 JSON(注意:unescaped 是字符串,不是 dict)</h1><p>data = json.loads(unescaped) # ✅ 成功:{'name': '张三', 'tag': '热销&爆款'}
</p>
从 HTML 文本中提取 JSON 字符串时,编码声明无关紧要
很多人卡在“HTML 文件用的是 GBK 还是 UTF-8”,其实只要目标 JSON 字符串是完整出现在 HTML 源码里的(比如 <script>var data = {...}</script>),你只需要:
- 确保整个 HTML 文本已按其真实编码正确解码为 Python
str(例如用response.content.decode('gbk')或chardet推测后 decode) - 之后所有操作(正则提取、
html.unescape()、json.loads())都在 Unicode 字符串层面进行,不再涉及字节编码 -
<meta charset="UTF-8">或 HTTPContent-Type头只影响 HTML 解析阶段,不影响后续对其中字符串字段的 HTML 实体解码
别手动 replace() HTML 实体,容易漏、不可靠
写一堆 .replace('"', '"').replace('&', '&')... 看似简单,但问题很多:
- 遗漏冷门实体,比如
'(单引号)、'(十六进制)、'(十进制) - 误替换文本中本就该保留的实体(比如页面描述里写 “请使用 标签”,你不该把这里的
当 JSON 转义来处理)<li>顺序错误导致二次污染(比如先 replace <code>&再 replace<,结果把<变成后又错当 <code> 处理)html.unescape()是唯一经过 HTML 规范验证的解法,它只作用于真正的实体边界,安全且完备。真正容易被忽略的是:HTML 实体解码和 JSON 解析必须分两步做,且中间不能插入任何字符串拼接或部分替换 —— 否则你永远不知道下一个报错来自编码、转义还是语法本身。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










