🎯 一款可定制、具备反检测功能的云浏览器,由自主研发的 Chromium驱动,专为网页爬虫AI 代理设计。👉立即试用
返回博客

resiliparse 网页抓取:快速 HTML 转文本提取

Emily Chen
Emily Chen

Advanced Data Extraction Specialist

23-Jul-2026

TL;DR:

  • resiliparse快速将HTML转换为干净文本,使用一个C++提取核心,旨在以十亿页规模处理网络档案。
  • main_content=True剔除了冗余信息。 它返回文章文本,而不包括导航、登录和页脚信息,这些在简单的文本提取中通常会保留。
  • resiliparse不进行抓取。 它没有HTTP客户端,也不运行JavaScript;只需提供标记,它即可进行提取。
  • 此差距在一个脚本中显现。 对一个JavaScript渲染的演示页面进行简单GET请求,仅得到23个字符的文本;通过Scrapeless Universal Scraping API以js_render抓取同一URL则可以获得真实内容。
  • 指南中的提取是真实的。 实时运行将10,968个字符的渲染HTML减至1,469个字符的干净主体文本。
  • 抓取端免费开始。app.scrapeless.com创建您的Scrapeless API密钥。

resiliparse是什么,它又不是何物

resiliparse是ChatNoir Resiliparse工具包的解析和提取部分,由网络档案研究小组构建,旨在处理Common Crawl及类似语料库。它的HTML到文本提取运行在一个C++核心中,这就是为什么在输入是数百万文档而非单一文档时它依然保持快速。您最常用的功能是extract_plain_text,其main_content=True模式是有用的部分:它剥离了导航、侧边栏和页脚,这些通常会让原始文本提取变得嘈杂,只留下读者真正想要的内容。

这是一个提取库,而不是抓取器。resiliparse没有HTTP客户端,不保持会话,也不运行JavaScript。给它一个字符串或字节,它返回文本;如果让它抓取一个URL,则没有方法做到这一点。因此,每个“resiliparse网络抓取”设置是两个层次:返回忠实HTML的东西,以及从中提取内容的resiliparse。本指南使用Scrapeless Universal Scraping API作为第一层,因为普通HTTP客户端在任何使用JavaScript构建内容的页面上返回的是预渲染的markup——而空markup提取到的也是空文本。有关结构化字段而非可读文本,Python网络抓取教程涵盖了基于选择器的路线。

安装

resiliparse和requests是整个工具链。本指南是基于resiliparse 1.0.9编写的:

bash Copy
pip install "resiliparse==1.0.9" requests

请将密钥保存在环境变量中,而不是源代码中:

bash Copy
export SCRAPELESS_API_KEY="sk_your_scrapeless_key"

获取值得提取的HTML

提取质量由抓取的忠实度决定,所以从这里开始。在JavaScript渲染的页面上,普通HTTP客户端收到的markup不包含任何内容——只有在脚本构建DOM之后,内容才会到达,这个生命周期由HTML脚本规范定义。一个脚本展示了resiliparse从每个页面获得什么:

python Copy
# fidelity.py — resiliparse提取的内容:普通GET与服务器端渲染
import os

import requests
from resiliparse.extract.html2text import extract_plain_text

URL = "https://quotes.toscrape.com/js/"
MARKER = "我们创造它的世界"

plain = requests.get(URL, timeout=60).text
plain_text = extract_plain_text(plain, main_content=True)
print("普通文本字符数:", len(plain_text), "| 包含引述:", MARKER in plain_text)

resp = requests.post(
    "https://api.scrapeless.com/api/v2/unlocker/request",
    headers={"Content-Type": "application/json", "x-api-token": os.environ["SCRAPELESS_API_KEY"]},
    json={"actor": "unlocker.webunlocker", "input": {"url": URL, "js_render": True}},
    timeout=120,
)
resp.raise_for_status()
rendered_text = extract_plain_text(resp.json().get("data", ""), main_content=True)
print("渲染文本字符数:", len(rendered_text), "| 包含引述:", MARKER in rendered_text)

普通的抓取提取几乎为空;而渲染的返回则带来了真实内容:

text Copy
普通文本字符数: 23 | 包含引述: False
渲染文本字符数: 1435 | 包含引述: True

渲染、解锁和代理路由都在那一次POST中服务器端完成——Universal Scraping API是抓取层,而渲染的字节是resiliparse应提取的内容。

提取干净的文本

在手中有了真实的HTML,resiliparse进行提取。运行一次默认配置,再运行一次main_content=True以查看冗余信息的剔除:

python Copy
# extract.py — 全文与主体内容提取
import os

import requests

来自resiliparse.extract.html2text的导入extract_plain_text

resp = requests.post(
"https://api.scrapeless.com/api/v2/unlocker/request",
headers={"Content-Type": "application/json", "x-api-token": os.environ["SCRAPELESS_API_KEY"]},
json={"actor": "unlocker.webunlocker", "input": {"url": "https://quotes.toscrape.com/", "js_render": True}},
timeout=120,
)
resp.raise_for_status()
html = resp.json().get("data", "")

full = extract_plain_text(html)
main = extract_plain_text(html, main_content=True)
print("渲染的 HTML 字符数:", len(html))
print("完整文本字符数:", len(full))
print("主要内容字符数:", len(main))
print("包含首个引用:", "我们创造的世界" in main)

运行将 10,968 个字符的 HTML 转换为可读文本,而 main_content 进一步修剪了内容:

text Copy
渲染的 HTML 字符数: 10968
完整文本字符数: 1674
主要内容字符数: 1469
包含首个引用: True

这就是整个流水线:一次 POST 请求以获取和渲染,一次调用以提取。 main_content=True 是使输出能够为语言模型或搜索索引提供干净数据的关键——导航和登录提示被完全文本转储所保留,现在消失了,引用文本仍然存在。

在免费计划中获取您的 API 密钥:app.scrapeless.com

高级模式

  • 在编码不确定时,传递字节而不是解码后的字符串。 resiliparse 从文档中检测编码;将原始响应字节传递给它可以避免双重解码,这可能会损坏非 ASCII 文本。
  • 使用 alt_textslinks 标志来保留或丢弃细节。 extract_plain_text 接受可以保留图像替代文本或链接目标的标志,必要时保留,不必要时省略。
  • 当您需要结构树时,请使用 resiliparse.parse.html 该工具包还暴露了一个 HTML 树和选择器 API,因此当纯文本不足时,您可以从相同的快速核心中提取结构化字段。
  • 保持提取和获取步骤分开。 提取是 CPU 绑定,而获取是 IO 绑定;先拉取页面,然后在批次上运行提取,使得两者互不依赖。

故障排除

  • 从可在浏览器中看到的页面中几乎没有文本。 内容是 JavaScript 渲染的,而您获取的是预渲染 HTML。第一个脚本的 23 个字符的结果正好是这个情况;通过 js_render 在获取层进行修复。
  • 输出中有导航和页脚文本。 您在没有使用 main_content=True 的情况下调用了 extract_plain_text。将其打开以删除模板文本。
  • 乱码的重音字符。 您向 resiliparse 提供了一个解码错误的字符串。传递响应字节,让它检测编码。
  • 您想要的内容被修剪了。 main_content 设计上是激进的。对于具有不寻常结构的页面,比较完整文本输出,当主要内容提取丢失太多时可回退至完整文本输出。

结论

resiliparse 赢得了作为可扩展提取层的地位:一个 C++ 核心,快速将 HTML 转换为干净文本,带有一个 main_content 模式,去除了多余部分。决定是否可行的层是提取 —— 第一个脚本的 23 与 1,435 字符的分割解决了这个问题 —— 一次服务器渲染的 POST 弥补了这一差距。将两者连接在一起,渲染页面变成干净文本,准备好用于索引或模型。

创建一个免费的 Scrapeless 账户以获取 API 密钥,且开发者文档涵盖了 unlocker.webunlocker 参数。当您计划定期作业时,请查看 Scrapeless 定价

常见问题

问:resiliparse 能单独抓取网站吗?

不行。resiliparse 从您已有的 HTML 中提取文本;它没有 HTTP 客户端,也不执行 JavaScript。将它与提取层配对——在这里是 Scrapeless 通用抓取 API,它在服务器端渲染页面——然后 resiliparse 处理从返回字节中提取文本。

问:resiliparse 和像 trafilatura 的去模板工具有什么不同?

两者都去除模板,但 resiliparse 来自 Web Archive 研究组,是用 C++ 构建用于大规模语料库处理,并作为更广泛的工具包的一部分发货,该工具包还读取 WARC 文件并检测编码和语言。当处理多个文档的速度成为限制时,请使用它。

问:main_content=True 实际上有什么作用?
它运行一个内容提取过程,保留主要文章文本,删除导航、侧边栏、标题和页脚。本指南中的比较显示了修剪后的输出与完整文本输出的对比,以便你可以看到哪些内容被去掉。

问:resiliparse能处理JavaScript渲染的页面吗?

不行 — 它不会执行脚本。如果内容在初始HTML之后加载,普通的提取几乎不会得到任何内容,如23个字符的结果所示。请首先通过Scrapeless API使用js_render提取页面,然后再提取内容。

问:使用resiliparse进行抓取合法吗?

提取库并没有改变收集规则。只获取公共页面,遵守网站条款和由机器人排除协议标准化的机器人指令,保持数据量在合理范围内,并根据适用的法律处理任何个人数据。

在Scrapeless,我们仅访问公开可用的数据,并严格遵循适用的法律、法规和网站隐私政策。本博客中的内容仅供演示之用,不涉及任何非法或侵权活动。我们对使用本博客或第三方链接中的信息不做任何保证,并免除所有责任。在进行任何抓取活动之前,请咨询您的法律顾问,并审查目标网站的服务条款或获取必要的许可。

最受欢迎的文章

目录