这不是乱码,是html实体编码(html entity)——网页源码里用

为什么爬虫拿到的文本里有
这不是乱码,是HTML实体编码(HTML entity)——网页源码里用 代替 <code>、<code>& 代替 &,防止浏览器误解析。requests + BeautifulSoup 默认不自动解码,所以你看到的是原始实体字符串。
用 html.unescape() 最快解码纯文本
如果只是处理一段字符串(比如从 elem.get_text() 或 elem.text 拿到的),直接调 html.unescape() 就行,Python 标准库自带,不用装额外包:
import html raw = "Hello & welcome to "Python" <world>" clean = html.unescape(raw) # → "Hello & welcome to "Python" <world>"</world></world>
- 只对标准 HTML 实体生效(
、<code>>、&、"、'和数字实体如A) - 不处理富文本里的标签结构,也不修复嵌套或拼写错误的实体(比如
<b>不会变成<b></b>) - 性能好,适合批量清洗字段级文本
BeautifulSoup 解析时就解码:用 .get_text() 而不是 .text
.text 返回原始节点内容(含未解码实体),.get_text() 内部调用了更完整的解码逻辑,尤其对嵌套标签和混合实体更鲁棒:
from bs4 import BeautifulSoup
soup = BeautifulSoup("<p>Price: USD</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill2570" title="Baoyu Markdown To Html"><img
src="https://img.php.cn/upload/skill/000/000/081/178918939167217.jpg" alt="Baoyu Markdown To Html" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill2570" title="Baoyu Markdown To Html" class="overflowclass">Baoyu Markdown To Html</a>
<p class="overflowclass">将 Markdown 转换为微信兼容的样式化 HTML,支持代码高亮、数学公式、PlantUML、脚注、提示框、信息图以及可选机器人...</p>
</div>
<a rel="nofollow" href="/xiazai/skill2570" title="Baoyu Markdown To Html" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>", "html.parser")
print(soup.p.text) # → "<p>Price: $10 USD</p>"(错)
print(soup.p.get_text()) # → "Price: $10 USD"(对, 变成不间断空格)
-
.get_text()会递归遍历子节点,并在拼接前对每个文本节点调用类似html.unescape()的处理 - 对
、©等命名实体支持更好,.text常常原样保留 - 如果需要保留换行或控制分隔符,可传参:
.get_text(separator=" ", strip=True)
遇到 • 这类十六进制实体怎么办?
html.unescape() 支持 {(十进制)和 {(十六进制),但前提是字符串里确实是合法格式。常见坑是:实体被截断(如 Ȃ)、混在 JS 字符串里、或被反爬插入了干扰字符。
- 先用正则粗筛:
re.sub(r'([0-9a-fA-F]{4});', r'\u', s)再用encode().decode('unicode_escape')是高风险操作,容易报错 - 更稳的做法:仍走
html.unescape(),但确保输入是完整 HTML 片段(哪怕只是<div>{s}</div>包一层再 parse) - 如果实体来自 JSON 响应或 API 接口,检查是否本就是服务端返回的已编码字符串——这时要确认接口文档是否声明“内容已 HTML 编码”,避免重复解码
实体解码看着简单,实际依赖上下文:是纯文本字段?还是 HTML 片段?有没有 JS 动态渲染?没看清来源就硬 unescape,可能把本该保留的 & 变成 & 导致后续解析失败。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










