这是一篇 2000 多字的博客文章,内容是“如何在 Python 中将 HTML 转换为文本?”:
HTML 是在网络上存储和显示数据的重要格式。当网页抓取时,我们通常只想从 HTML 页面中提取可见的文本内容。在这篇文章中,我将探索在 Python 中将 HTML 转换为干净文本的不同技术。
为什么要将 HTML 转换为文本?
您可能想要剥离 HTML 标签并仅提取文本的主要原因有几个:
简化抓取的内容 – 抓取网页时,HTML 通常包含许多我们不需要的额外标记和元素,例如导航链接。提取正文使内容更易于分析和使用。
删除格式 – HTML 应用视觉格式和布局。对于情感分析等许多应用程序,我们只需要不带任何格式的文本内容。
以文本格式存储 – 仅从 HTML 中提取文本非常有用,因此可以将其存储为简单的格式,例如文本文件或数据库文本字段。这会删除所有庞大的 HTML 标记。
可读性 – 原始 HTML 人类很难阅读和解释。转换为文本使其更具可读性。
无障碍 – 视力障碍用户使用的屏幕阅读器更容易访问纯文本内容。
搜索引擎索引 – 搜索引擎主要分析和索引页面的可见文本内容。将 HTML 转换为文本可以帮助分析内容,就像搜索引擎如何看待它一样。
总之,从 HTML 中提取文本对于抓取、分析、存储和可访问性很有用。接下来的部分将介绍在 Python 中实现此目的的不同方法。
使用 BeautifulSoup 剥离 HTML 标签
Beautiful Soup 是一个流行的 Python 库,用于网页抓取和解析 HTML。我们可以使用它相当轻松地从 HTML 中提取文本。
最简单的方法是调用 get_text()
BeautifulSoup 对象或从解析的 HTML 中选择的元素上的方法。例如:
from bs4 import BeautifulSoup
html = """<p>Here is a paragraph with <a href="http://example.com">a link</a>."""
soup = BeautifulSoup(html, "html.parser")
text = soup.get_text()
print(text)
# Output: Here is a paragraph with a link.
这会去除所有 HTML 标签并返回包含可见文本的字符串。
有一点需要注意的是 get_text()
默认情况下也会将多个连续的空白字符压缩为一个空格。经过 strip=False
保留空白,如换行符和额外空格:
text = soup.get_text(strip=False)
print(text)
# Output:
#
# Here is a paragraph with
# a link.
要仅从 HTML 的一部分中提取文本,请调用 get_text()
在一个元素而不是整个文档上:
el = soup.select_one("p")
text = el.get_text()
print(text)
# Output: Here is a paragraph with a link.
需要注意的是 get_text()
仍将包含嵌套在子元素(如链接)内的任何文本。也要把它们去掉,传递一个 recursive=False
参数:
text = el.get_text(recursive=False)
print(text)
# Output: Here is a paragraph with
所以有了BeautifulSoup我们就可以轻松使用 get_text()
从 HTML 中提取可见文本。
使用 lxml 提取文本
xml文件 是另一个流行的用于解析 XML 和 HTML 的 Python 库。我们也可以用它来提取文本。
来自 lxml HTMLParser
元素,调用 text_content()
获取文本的方法:
from lxml.html import fromstring, HTMLParser
html = """<p>Here is a paragraph with <a href="http://example.com">a link</a>.</p>"""
tree = fromstring(html, parser=HTMLParser())
text = tree.text_content()
print(text)
# Output: Here is a paragraph with a link.
这将递归地提取所有文本,包括子元素中的文本。要排除子项中的文本,请传递 children=False
参数:
text = tree.text_content(children=False)
print(text)
# Output: Here is a paragraph with
因此lxml还提供了一种简单的方法来剥离HTML并仅获取文本内容。
常用表达
基于正则表达式的方法也可用于删除 HTML 标签。这涉及使用模式来匹配所有 HTML 标签,并用替换来替换它们:
import re
html = """<p>Here is a paragraph with <a href="http://example.com">a link</a>.</p>"""
clean = re.sub(r"<[^>]*>", "", html)
print(clean)
# Output: Here is a paragraph with a link.
正则表达式 r"<[^>]*>"
火柴 <
后面跟任何东西除了 >
一次或多次,然后 >
。 该 re.sub()
调用会删除这些匹配项,从而有效地删除所有 HTML 标签。
还可以处理 XML 命名空间和自结束标签:
clean = re.sub(r"<[^>]+>", "", html)
这是一种快速、简单的基于正则表达式的方法,用于去除所有 HTML 标签。尽管它不提供与 BeautifulSoup 和 lxml 等特定 HTML 解析库相同的控制和简单性。
处理编码
网页可以采用各种文本格式进行编码,例如 ASCII、UTF-8 或 ISO-8859-1。当抓取页面时,我们想要检测编码并正确解码为 Unicode 文本。
chardet
库可以自动为我们检测编码:
import chardet
html = b"<p>Hello world</p>"
encoding = chardet.detect(html)["encoding"]
if encoding:
html = html.decode(encoding)
else:
html = html.decode("utf-8")
print(html)
然后,我们可以在解析和提取文本之前将 HTML 字节显式解码为 Unicode 字符串。
将 HTML 转换为文本时,应在解析之前先处理编码,以避免编码错误。
完整的 HTML 到文本示例
下面是一个示例,将所涵盖的步骤放在一起,以稳健地从 HTML 中提取文本:
from bs4 import BeautifulSoup
import chardet
import re
def html_to_text(html):
# Detect encoding
encoding = chardet.detect(html)["encoding"]
if encoding:
html = html.decode(encoding)
else:
html = html.decode("utf-8")
# Remove tags
clean = re.sub(r"<[^>]+>", "", html)
# Extract text
soup = BeautifulSoup(clean, "html.parser")
text = soup.get_text(strip=True)
return text
html = """<p>Here is a paragraph with <a href="http://example.com">a link</a>.</p>"""
print(html_to_text(html))
# Output: Here is a paragraph with a link.
它处理编码检测、剥离标签以及在可重用函数中提取文本。
还有一些 Python 库,例如 提取物 封装了一些将各种文件格式转换为文本的功能。
转换 HTML 实体
我们可能遇到的另一个问题是 HTML 使用字符实体,例如
和 &
而不是字面字符。
我们可以使用 html.unescape()
Python 标准中的函数 html库 将实体转换回字符:
import html
text = " Bread & Butter"
print(html.unescape(text))
# Output: Bread & Butter
这可以在从 HTML 中提取文本之前或之后完成。
处理 JavaScript
上述技术的局限性是它们仅从初始 HTML 中提取可见文本。任何由 JavaScript 动态添加的文本都不会被捕获。
要执行 JavaScript 并呈现全文,我们需要使用无头浏览器,例如 硒 or 剧作家:
from playwright.sync_api import sync_playwright
html = """<p>Hello</p><script>document.body.innerHTML += "<p>World</p>";</script>"""
with sync_playwright() as p:
browser = p.webkit.launch()
page = browser.new_page()
page.content = html
text = page.content()
browser.close()
print(text)
# Output: <p>Hello</p><p>World</p>
这里 Playwright 用于加载页面并执行 JavaScript,使我们能够提取完整的文本。
因此,对于具有大量 JS 操作的页面,如果我们需要完整渲染的文本,则可能需要浏览器自动化工具。
总结
在 Python 中将 HTML 转换为纯文本有以下几种主要技术:
- 使用
get_text()
来自 美丽汤 - 提取内容
text_content()
在 lxml 中 - 使用正则表达式删除标签
- 在解析之前解码任何编码
- 处理 HTML 实体
html.unescape()
- 如果需要执行 JavaScript,请使用无头浏览器
将 HTML 转换为文本对于简化抓取的内容、分析文本而不是标记、提高可读性和可访问性、通过搜索引擎建立索引以及以轻量级格式存储非常有用。
我希望这篇文章能够为使用 Python 从 HTML 中提取文本的主要方法提供全面的指南!如果您有任何其他有用的技术,请告诉我。