🚀使用Readability.js清洗HTML内容,打造RAG高质量数据

🚀使用Readability.js清洗HTML内容,打造RAG高质量数据

原文链接:Clean up HTML Content for Retrieval-Augmented Generation with Readability.js

作者:Phil Nash

译者:倔强青铜三

前言

大家好,我是倔强青铜三 。是一名热情的软件工程师,我热衷于分享和传播IT技术,致力于通过我的知识和技能推动技术交流与创新,欢迎关注我,微信公众号:倔强青铜三。欢迎点赞、收藏、关注,一键三连!!!

从网页抓取内容是为您的 检索增强生成 (RAG) 应用程序获取内容的一种方法。但解析网页内容可能会很麻烦。

Mozilla 的开源库 Readability.js 是提取网页重要部分的有用工具。让我们看看如何将其用作 RAG 应用程序数据摄取管道的一部分。

从网页检索非结构化数据

网页是我们可以在基于 RAG 的应用程序中使用的非结构化数据来源。但网页通常包含许多无关内容,例如页眉、侧边栏和页脚。这些内容对于浏览网站的人来说是有用的上下文,但会分散页面主要内容的注意力。

为了为 RAG 获取最佳数据,我们需要删除无关内容。当您在一个网站内工作时,可以使用像 cheerio 这样的工具根据您对网站结构的了解自行解析 HTML。但如果您要抓取不同布局和设计的页面,则需要一种好的方法来返回相关内容并避免其余部分。

重新利用阅读视图

大多数网络浏览器都带有阅读视图,可以剥离除文章标题和内容之外的所有内容。以下是应用于 DataStax 网站博客文章时浏览器和阅读模式的区别。

Mozilla 将 Firefox 阅读模式的底层库作为独立的开源模块提供:Readability.js。因此,我们可以在数据管道中使用 Readability.js 来剥离无关内容,并从抓取的网页中返回高质量的结果。

如何使用 Node.js 和 Readability.js 抓取数据

让我们看看一个从我之前关于 在 Node.js 中创建向量嵌入 的博客文章中抓取文章内容的示例。以下是您可以用来检索页面 HTML 的一些 JavaScript 代码:

JavaScript 复制代码
const html = await fetch("https://www.datastax.com/blog/how-to-create-vector-embeddings-in-node-js")
  .then((res) => res.text());
console.log(html);

这包括所有 HTML 标签以及导航、页脚、分享链接、行动号召以及大多数网站上的其他内容。

为了改进这一点,您可以安装像 cheerio 这样的模块并仅选择重要部分:

bash 复制代码
npm install cheerio
JavaScript 复制代码
import * as cheerio from "cheerio";

const html = await fetch("https://www.datastax.com/blog/how-to-create-vector-embeddings-in-node-js")
  .then((res) => res.text());

const $ = cheerio.load(html);

console.log($("h1").text(), "\n");
console.log($("section#blog-content > div:first-child").text());

使用此代码,您可以获得文章的标题和文本。正如我之前所说,如果您了解 HTML 的结构,这非常有用,但情况并不总是如此。

相反,安装 Readability.jsjsdom

bash 复制代码
npm install @mozilla/readability jsdom

Readability.js 通常在浏览器环境中运行并使用实时文档,而不是 HTML 字符串,因此我们需要在 Node.js 中包含 jsdom 以提供该功能。现在,我们可以将已经加载的 HTML 转换为文档,并将其传递给 Readability.js 以解析内容。

JavaScript 复制代码
import { Readability } from "@mozilla/readability";
import { JSDOM } from "jsdom";

const url = "https://www.datastax.com/blog/how-to-create-vector-embeddings-in-node-js";
const html = await fetch(url).then((res) => res.text());

const doc = new JSDOM(html, { url });
const reader = new Readability(doc.window.document);
const article = reader.parse();

console.log(article);

当您检查文章时,可以看到它从 HTML 中解析了许多内容。

有标题、作者、摘要、发布时间以及内容和 textContent。textContent 属性是文章的纯文本内容,已准备好让您 将其拆分为块创建向量嵌入摄取到 Astra DB。content 属性是原始 HTML,包括链接和图像。如果您想提取链接或以某种方式处理图像,这可能会有用。

您可能还希望查看文档是否可能返回良好的结果。阅读视图在文章上效果很好,但对其他类型的内容用处不大。您可以使用 isProbablyReaderable 函数快速检查 HTML 是否适合使用 Readability.js 进行处理。如果该函数返回 false,您可能需要以不同的方式解析 HTML,甚至检查 URL 是否包含对您有用的内容。

JavaScript 复制代码
const doc = new JSDOM(html, { url });
const reader = new Readability(doc.window.document);

if (reader.isProbablyReaderable(doc.window.document)) {
  const article = reader.parse();
  console.log(article);
} else {
  // 做其他事情
}

如果页面未通过此检查,您可能希望标记 URL 以查看它是否包含对您的 RAG 应用程序有用的信息,或者是否应将其排除。

使用 Readability 与 LangChain.js

如果您的应用程序使用LangChain.js,您也可以使用 Readability.js 返回 HTML 页面的内容。它非常适合您的数据摄取管道,并与其他 LangChain 组件一起使用,例如 文本分块器向量存储

以下示例使用 LangChain.js 加载上述相同页面,使用 MozillaReadabilityTransformer 返回页面的相关内容,使用 RecursiveCharacterTextSplitter 将文本拆分为块,使用 OpenAI 创建向量嵌入,并将数据存储在 Astra DB 中。

您需要安装以下依赖项:

bash 复制代码
npm install @langchain/core @langchain/community @langchain/openai @datastax/astra-db-ts @mozilla/readability jsdom

要运行示例,您需要创建一个 Astra DB 数据库,并将数据库的端点和应用程序令牌存储在您的环境中,分别为 ASTRA_DB_APPLICATION_TOKENASTRA_DB_API_ENDPOINT。您还需要一个存储在环境中的 OpenAI API 密钥,名为 OPENAI_API_KEY

导入依赖项:

JavaScript 复制代码
import { HTMLWebBaseLoader } from "@langchain/community/document_loaders/web/html";
import { MozillaReadabilityTransformer } from "@langchain/community/document_transformers/mozilla_readability";
import { RecursiveCharacterTextSplitter } from "@langchain/textsplitters";
import { OpenAIEmbeddings } from "@langchain/openai";
import { AstraDBVectorStore } from "@langchain/community/vectorstores/astradb";

我们使用 HTMLWebBaseLoader 从我们提供的 URL 加载原始 HTML。HTML 然后通过 MozillaReadabilityTransformer 提取文本,随后由 RecursiveCharacterTextSplitter 将其拆分为块。最后,我们创建一个嵌入提供程序和一个 Astra DB 向量存储,用于将文本块转换为向量嵌入并存储在向量数据库中。

JavaScript 复制代码
const loader = new HTMLWebBaseLoader("https://www.datastax.com/blog/how-to-create-vector-embeddings-in-node-js");
const transformer = new MozillaReadabilityTransformer();
const splitter = new RecursiveCharacterTextSplitter({
  maxCharacterCount: 1000,
  chunkOverlap: 200,
});
const embeddings = new OpenAIEmbeddings({
  model: "text-embedding-3-small",
});
const vectorStore = new AstraDBVectorStore(embeddings, {
  token: process.env.ASTRA_DB_APPLICATION_TOKEN,
  endpoint: process.env.ASTRA_DB_API_ENDPOINT,
  collection: "content",
  collectionOptions: {
    vector: {
      dimension: 1536,
      metric: "cosine",
    },
  },
});
await vectorStore.initialize();

所有组件的初始化构成了大部分工作。一旦一切设置完成,您可以像这样加载、转换、拆分、嵌入和存储文档:

JavaScript 复制代码
const docs = await loader.load();
const sequence = transformer.pipe(splitter);
const vectorizedDocs = await sequence.invoke(docs);
await vectorStore.addDocuments(vectorizedDocs);

使用 Readability.js 更准确地抓取网页数据

Readability.js 是一个经过实战考验的库,为 Firefox 的阅读模式提供支持,我们可以使用它仅从网页中抓取相关数据。这清理了网页内容,使其对 RAG 更加有用。

正如我们所见,您可以直接使用该库,或者使用 LangChain.js 和 MozillaReadabilityTransformer

从网页获取数据只是您摄取管道的第一步。从这里,您需要将文本拆分为块,创建向量嵌入,并将所有内容存储在 Astra DB 中。然后,您就可以构建您的 RAG 驱动应用程序了。

最后感谢阅读!欢迎关注我,微信公众号倔强青铜三。欢迎点赞收藏关注,一键三连!!!

相关推荐
a堅強的泡沫8 分钟前
【React】实现TagInput输入框,可以输入多个邮箱并校验是否合法
前端·javascript·react.js
成长之旅34 分钟前
idea Ai工具通义灵码,Copilot我的使用方法以及比较
人工智能·intellij-idea·copilot
LLLuckyGirl~35 分钟前
webpack配置之---output.chunkLoadTimeout
前端·webpack·node.js
AI_Gump39 分钟前
【AI实践】Cursor上手-跑通Hello World和时间管理功能
人工智能·ai
test猿1 小时前
深度学习 - 神经网络的原理
人工智能·深度学习·神经网络
GesLuck1 小时前
C#控件开发6—旋转按钮
开发语言·javascript·c#
青云交1 小时前
解锁 DeepSeek 模型高效部署密码:蓝耘平台深度剖析与实战应用
大数据·人工智能·技术融合·deepseek 模型·智能金融监管·deepseek-r1_32b·java 大数据
程序员小续2 小时前
现代前端工程化实践:高效构建的秘密
开发语言·前端·javascript·vue.js·webpack·前端框架·ecmascript
RickZhou2 小时前
React 个人博客 支持自定义主题
前端
林啾啾2 小时前
按钮凸起与按下css效果
前端·css