4人参与 • 2026-09-18 • Python
爬虫开发中,拿到 http 返回的 html 原始源码并不是终点。原始页面经常夹杂 bom 标记、多余空白、无效注释、转义字符、不规范标签,直接拿去解析、提取文本、做相似度对比或者文件类型判断,很容易踩各种隐形大坑。
html 预处理,本质是在正式解析之前,对原始网页做清洗、规整。它不等同于 html 压缩,压缩更多是为减小体积;预处理目标更宽泛:修复脏数据、消除干扰项,为后续 xpath / css选择器 / 文本提取提供干净可靠的输入。
本文结合爬虫实战,梳理一套完整的 html 预处理流水线,覆盖从原始 bytes 到干净文本的全流程。
一套标准预处理流程顺序(非常关键,顺序不能乱):
重点提醒:操作顺序建议:bytes处理 → 解码 → 文本清洗。不要先解码再处理bom,会引入不必要的
\ufeff字符。
网页由windows服务器或记事本生成时,很容易在最前面带上b'\xef\xbb\xbf'。
它不属于html正文,但是会干扰魔数判断、前缀匹配,lstrip()无法自动移除。
def strip_bom_and_prefix_whitespace(raw_bytes: bytes) -> bytes:
# 移除utf-8 bom
if raw_bytes.startswith(b"\xef\xbb\xbf"):
raw_bytes = raw_bytes[3:]
# 剔除文档开头空白(空格、换行、tab、回车)
raw_bytes = raw_bytes.lstrip(b" \r\n\t")
return raw_bytes
这一步对应我们之前写的detect_file_type函数,在解码之前执行,性能更高,规避解码异常。
很多网页content-type里写的编码和页面meta声明不一致,直接用resp.content.decode("utf-8")大概率乱码。
推荐使用cchardet/chardet自动探测编码。
pip install cchardet
import cchardet
def decode_html(raw_bytes: bytes) -> str:
detect_result = cchardet.detect(raw_bytes)
encoding = detect_result["encoding"] or "utf-8"
try:
return raw_bytes.decode(encoding)
except exception:
# 探测编码失败时兜底
return raw_bytes.decode("utf-8", errors="replace")
小技巧:可以优先从response headers、html meta标签提取charset,优先级高于自动探测,准确率更高。
这里要区分两种场景:
❌ 禁止简单正则全局删除空白,<pre> <textarea> <script> <style>内部的空白不能随意清除。
import re
import htmlmin
def clean_html_text(html: str, remove_comments=true) -> str:
if remove_comments:
# 删除html注释,注意:不会处理script内部注释
html = re.sub(r"<!--[\s\s]*?-->", "", html)
# 轻量清洗,保留pre/script/style内部格式
html = htmlmin.minify(html, remove_comments=false, remove_all_empty_space=false)
return html
如果我们只需要提取正文文本,不需要js、css,可以直接删除script、style标签,减少解析开销:
from bs4 import beautifulsoup
def remove_useless_tags(html: str) -> str:
soup = beautifulsoup(html, "html.parser")
for tag in soup(["script", "style", "noscript"]):
tag.decompose()
return str(soup)
注意:移除script/style会改变页面dom结构,如果你的业务需要执行js、提取内嵌css,不能使用这一步。
组合上面所有步骤,搭配requests,形成可直接复用的预处理函数:
import requests
import cchardet
import htmlmin
from bs4 import beautifulsoup
def preprocess_html(resp: requests.response) -> str:
# 1. 获取原始二进制,清理bom和前置空白
raw_bytes = resp.content
if raw_bytes.startswith(b"\xef\xbb\xbf"):
raw_bytes = raw_bytes[3:]
raw_bytes = raw_bytes.lstrip(b" \r\n\t")
# 2. 编码探测并解码
detect_result = cchardet.detect(raw_bytes)
encoding = detect_result["encoding"] or "utf-8"
try:
html_str = raw_bytes.decode(encoding)
except exception:
html_str = raw_bytes.decode("utf-8", errors="replace")
# 3. 删除注释
html_str = re.sub(r"<!--[\s\s]*?-->", "", html_str)
# 4. 移除script/style标签(按需开启)
soup = beautifulsoup(html_str, "html.parser")
for tag in soup(["script", "style"]):
tag.decompose()
html_str = str(soup)
# 5. 轻量清洗多余空白
html_str = htmlmin.minify(html_str, remove_comments=false, remove_all_empty_space=false)
return html_str
if __name__ == "__main__":
r = requests.get("[https://example.com](https://example.com)")
clean_html = preprocess_html(r)
print(clean_html)
\ufeff,容易被忽略,干扰文本匹配。< &这类实体,一般保留原样;只有提取纯文本展示时才调用html.unescape()。html预处理不是简单的“删空格”,而是一套分层清洗流水线:二进制预处理优先,然后处理编码,再做dom清洗。
根据业务选择清洗力度:类型检测尽量不解码;dom解析用bs4安全移除无用标签;归档场景再开启压缩。
在爬虫项目中,把bom清洗、编码探测、注释清理、无用标签移除封装成独立预处理函数,可以极大减少后续解析环节的各种诡异bug。
以上就是python对html进行预处理的全流程的详细内容,更多关于python对html预处理的资料请关注代码网其它相关文章!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论