AI 日报

数据采集新篇章:AI与大模型的融合应用

  • By 51ITO
  • Jan 18, 2024 - 2 min read



作者 | 崔皓

审校 | 重楼

开篇

在AIGC(人工智能与通用计算)应用中,大型语言模型(LLM)占据着举足轻重的地位。这些模型,如GPT和BERT系列,通过处理和分析庞大的数据集,已经极大地推动了自然语言理解和生成的边界。它们在多种应用中表现出色,如文本生成、语言翻译、情感分析等,对提高工作效率和展开创新的应用场景起着关键作用。

然而,LLM在处理实时数据方面存在一定的局限性。这些模型主要基于大量历史数据进行训练,因此,在理解和分析实时或最新信息时可能不够灵敏。在应对新兴话题或最新发展趋势时,LLM可能无法提供最准确的信息,因为这些内容可能尚未包含在其训练数据中。此外,LLM在快速处理和反应实时变化方面也面临挑战,尤其是在需要分析和反映最新市场动态、政策变化或社会事件时。

既然我们已经意识到了大型语言模型(LLM)在处理实时数据方面的局限性,那么下一步就是探索如何通过Web Research技术突破这一限制。下面的内容将专注于如何通过网络爬虫技术结合LLM,实现对实时网络资源的有效获取和分析。

整体思路

Web Research 结合 LLM 的整体思路是复杂的过程,旨在利用大型语言模型的自然语言处理能力,实现对互联网数据的高效处理和分析。如下图所示,我们将整个过程进行拆解

1. 实时网络请求:首先,对目标网站发起实时请求,以获取最新的数据和内容。

2. 获取HTML页面:使用网站的URLs来访问和加载HTML页面,此时,网页的数据将被加载到内存中。

3. 内容转换:随后,将加载的HTML页面转换为文本信息,为后续的处理步骤做准备。这通常涉及去除HTML标记和格式化内容,以提取纯文本数据。

4. 数据存储和分类:转换后的文本数据可以存储在向量库中,以便于进行高效的检索和分析。同时,可以利用LLM对内容进行分类和组织,以便快速访问相关信息。

5.生成摘要:最后,利用LLM的功能调用来生成文本数据的摘要。这不仅包括提取关键信息,还可能涉及对数据进行综合和解释,以便用户能够快速理解内容的核心要点。

通过这样的流程,我们能够结合LLM的强大文本处理功能和网络爬虫技术的实时数据访问能力,有效地处理和分析大量的在线信息。这种方法不仅提高了信息处理的速度和准确性,而且通过摘要和分类,使得用户能够更容易地获取和理解需要的数据。

关键问题

为了验证Web爬虫和大型语言模型结合的研究思路是否切实可行,可以以知名新闻网站Wall Street Journal(华尔街日报)为例进行实证分析。假设从该网站的首页,获取实时的新闻信息,并且将这些信息进行抽取,最终保存为包括“标题”和“摘要”的结构化信息, 以便后续查找和分析。从过程描述发现,将面临三个主要的技术挑战:加载、转换以及通过LLM进行内容抽取。

1.加载HTML:我们可以访问 https://www.wsj.com,使用网络爬虫工具获取网站的HTML内容。这一步涉及发送HTTP请求并接收返回的网页代码。

2. 转换为文本:分析该网站的HTML结构表明,文章标题和摘要信息通常包含在``标签中。如下图所示,文章的标题是在``标签中

如下图所示,我们观察到,文章的摘要也是保存在标签中。

因此需要利用HTML解析库,如BeautifulSoup,从HTML中提取这些标签的内容,并将其转换为纯文本格式。

3. LLM处理:有了纯文本数据后,我们将使用大型语言模型来进一步处理这些文本。这可能包括内容分类、关键信息提取、摘要生成等。

在这个例证中,我们将如何确保网络爬虫精准地抓取所需信息,以及如何调整大型语言模型以精确处理和提取有价值的内容,都是需要解决的问题。通过成功实施这一流程,我们不仅验证了LLM与Web爬虫结合的有效性,还进一步探索了如何通过自动化工具提高研究和分析的效率。

数据加载

通过上面对关键问题的分析,让我们先为即将进行的技术旅程做好准备。从网页内容的加载到信息的转换,再到利用LLM提取关键数据,都是构建有效网络研究工具的关键环节。

首先,我们将面对的挑战是如何高效地加载网页内容。异步HTML加载器(AsyncHtmlLoader)扮演着至关重要的角色。使用aiohttp库构建的AsyncHtmlLoader能够进行异步HTTP请求,非常适合于简单轻量级的网页抓取工作。这意味着它能够同时处理多个URL的请求,提高了数据抓取的效率,特别是当我们需要从多个网站快速获取信息时。

对于那些更复杂的网站,其中的内容可能依赖于JavaScript渲染,我们可能需要更强大的工具,例如AsyncChromiumLoader。这个加载器利用Playwright来启动一个Chromium实例,它不仅可以处理JavaScript渲染,还可以应对更复杂的Web交互。Playwright是一个强大的库,支持多种浏览器自动化操作,其中Chromium就是一个被广泛支持的浏览器。

Chromium可以在无头模式下运行,即没有图形用户界面的浏览器,这在网页抓取中很常见。在无头模式下,浏览器后台运行,执行自动化任务,而用户不会看到任何的浏览器窗口。这样的操作对于服务器端的抓取任务尤其有用,因为它们可以模拟浏览器中的完整用户交互过程,而不需要实际显示界面。

无头模式,或称为“无界面模式”,是一种在不打开图形界面的情况下运行应用程序的方式。想象一下,你的电脑在执行一些任务,如下载文件、刷新数据或运行一个复杂的计算过程,而这一切都在没有打开任何窗口的情况下静静进行。这正是无头模式的工作原理。

在Web开发和自动化测试领域,无头模式尤为有用。例如,开发者可能需要测试一个网页在不同浏览器中的表现,但并不需要真正地视觉上检查这些网页,而是要检查代码的运行结果。在这种情况下,他们可以使用无头模式的浏览器来模拟用户的行为,如点击链接、填写表单等,同时浏览器本身不会在屏幕上显示。

实际上我们介绍了AsyncHtmlLoaderAsyncChromiumLoader两种加载器,本例中我们使用前者就足够了,其示例代码如下:

from langchain.document_loaders import AsyncHtmlLoader
urls = ["https://www.wsj.com"]
loader = AsyncHtmlLoader(urls)
docs = loader.load()

代码创建一个加载器实例并传入需要抓取的URL列表。随后,调用`load`方法就会异步加载这些页面的内容。

文本转换

解决了数据加载的问题,让我们把目光向文本转换。文本转换是网络爬虫技术中的一个重要环节,它负责将抓取的HTML内容转换成便于处理的纯文本格式。在这一阶段,我们可以选用不同的工具,根据不同的需求来实现这一转换。

首先是HTML2Text,这是一个直接将HTML内容转换为纯文本的工具,生成的格式类似于Markdown。这种转换方法适合于那些目标是提取可读文本而不需要操作特定HTML标签的场景。它简化了转换流程,能够迅速提供一个干净的文本版本,适合阅读和进一步分析。

而Beautiful Soup则提供了更细粒度的控制能力。使用Beautiful Soup,我们可以执行特定标签的提取、删除和内容清理,这对于需要从HTML内容中提取特定信息的场景来说非常适合。例如,如果我们需要从一个新闻网站中提取文章标题和摘要,而这些内容是通过``标签来标识的,Beautiful Soup就可以精确地定位这些标签并提取它们的内容。

在实际操作中,我们可以先使用AsyncHtmlLoader来加载目标网站的文档。接着,我们可以使用Html2TextTransformer来对加载的HTML文档进行转换。如下代码所示:

from langchain.document_loaders import AsyncHtmlLoader
from langchain.document_transformers import Html2TextTransformer
urls = ["https://www.wsj.com"]
loader = AsyncHtmlLoader(urls)
docs = loader.load()
html2text = Html2TextTransformer()
docs_transformed = html2text.transform_documents(docs)

以上代码演示了如何将加载的HTML文档转换为文本。这样,我们就可以得到一个文本版本的文档,其中包含了从原始HTML中提取出来的文本内容。

信息抽取

当我们准备好了数据之后,接下来的重要步骤是数据的抽取,这是大型语言模型(LLM)发挥作用的时刻。网络爬虫面临的挑战之一是现代网站布局和内容不断变化,这要求我们不停地修改爬虫脚本以适应这些变化。通过结合OpenAI的功能调用(Function)和抽取链(Extraction Chain),我们可以避免在网站更新时不断更改代码。

为了确保我们能够使用OpenAI Functions特性,我们选择使用`gpt-3.5-turbo-0613`模型。同时,为了降低LLM的随机性,我们将温度参数(temperature)设置为0。

from langchain.chat_models import ChatOpenAI
llm = ChatOpenAI(temperature=0, model="gpt-3.5-turbo-0613")

接下来,我们定义一个数据抽取模式(Schema),以指定我们想要抽取的数据类型。在这里,关键字的命名非常重要,因为它们告诉LLM我们想要的信息类型。所以,描述时要尽可能详细。

例如,在本例中,我们想要从华尔街日报网站抽取新闻文章的标题和摘要。

from langchain.chains import create_extraction_chain
schema = {
    "properties": {
        "news_article_title": {"type": "string"},
        "news_article_summary": {"type": "string"},
    },
    "required": ["news_article_title", "news_article_summary"],
}

然后,我们可以定义一个抽取函数,它使用定义的模式和LLM来运行内容抽取。

def extract(content: str, schema: dict):
    return create_extraction_chain(schema=schema, llm=llm).run(content)

通过这种方式,LLM可以从文本中精确地抽取出我们需要的信息,并生成我们需要的结构化数据。这种结合了LLM的抽取链的方法,不仅提高了数据处理的准确性,也极大地简化了我们处理网站内容变化的工作。

代码实施

解决三个关键文字之后,我们将生成整体代码如下,代码展示了如何使用Playwright结合LangChain库来实现一个完整的网络爬虫和内容抽取的工作流。

import pprint
from langchain.text_splitter import RecursiveCharacterTextSplitter
def scrape_with_playwright(urls, schema):
    loader = AsyncChromiumLoader(urls)
    docs = loader.load()
    bs_transformer = BeautifulSoupTransformer()
    docs_transformed = bs_transformer.transform_documents(
        docs, tags_to_extract=["span"]
    )
    print("Extracting content with LLM")
    # Grab the first 1000 tokens of the site
    splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(
        chunk_size=1000, chunk_overlap=0
    )
    splits = splitter.split_documents(docs_transformed)
    # Process the first split
    extracted_content = extract(schema=schema, content=splits[0].page_content)
    pprint.pprint(extracted_content)
    return extracted_content
urls = ["https://www.wsj.com"]
extracted_content = scrape_with_playwright(urls, schema=schema)

下面是代码解释:

1. 首先,导入了必要的库和工具,包括用于打印的`pprint`和LangChain中的文本拆分器`RecursiveCharacterTextSplitter`。

2. 定义了一个`scrape_with_playwright`函数,该函数接收`urls`和`schema`作为参数。这里的`urls`是想要爬取的网站地址列表,而`schema`定义了想要从这些网页中抽取的数据结构。

3. 在函数内部,创建了一个`AsyncChromiumLoader`实例并传入了URL列表。这个加载器负责异步获取每个URL对应网页的HTML内容。

4. 接着,使用Beautiful Soup转换器`BeautifulSoupTransformer`来处理加载的HTML文档。在这个例子中,我们特别关注于``标签,因为我们假设这些标签包含了新闻文章的标题和摘要信息。

5. 使用`RecursiveCharacterTextSplitter`创建一个分割器实例,它基于给定的`chunk_size`(这里是1000个字符)来拆分文档内容。这是为了处理大型文档时,能够将其分割成小块以适应LLM处理的限制。

6. 处理拆分后的第一部分内容,并通过`extract`函数(需要定义)来抽取出符合`schema`定义的数据。

7. 最后,使用`pprint`打印出抽取的内容,并将其作为函数的返回值。

这个流程从头到尾将网页爬取、内容转换和数据抽取整合在一起,形成了一个端到端的解决方案,可以在不需要人工干预的情况下从网页中提取有结构的数据。

查看结果如下图所示,由于网页内容比较多,我们选取其中一组数据来观察,这里将新闻的标题和摘要进行了分割。

同时,结合之前研究网站页面的截图进行参考如下,“House Authorizes Formally Opening GOP’s Biden Impeachment Probe”这篇文章被我们通过网页加载、文本转换,大模型抽取的方式获得了。

总结

本文详细说明了利用网络爬虫技术和LLM结合的流程,通过案例分析验证了这一思路的可行性。从实时获取华尔街日报网站的数据开始,文章阐述了如何通过异步HTML加载器、文本转换工具、以及LLM进行精准的内容抽取,最终形成一个自动化、高效的网络研究工具。这不仅展示了LLM与网络爬虫技术结合的强大潜力,还探讨了如何提高研究和分析效率。

作者介绍

崔皓,51CTO社区编辑,资深架构师,拥有18年的软件开发和架构经验,10年分布式架构经验。