作者 | 崔皓
审校 | 重楼
开篇
在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结构表明,文章标题和摘要信息通常包含在`<span>`标签中。如下图所示,文章的标题是在`<span>`标签中。
如下图所示,我们观察到,文章的摘要也是保存在<span>标签中。
因此需要利用HTML解析库,如BeautifulSoup,从HTML中提取这些标签的内容,并将其转换为纯文本格式。
3. LLM处理:有了纯文本数据后,我们将使用大型语言模型来进一步处理这些文本。这可能包括内容分类、关键信息提取、摘要生成等。
在这个例证中,我们将如何确保网络爬虫精准地抓取所需信息,以及如何调整大型语言模型以精确处理和提取有价值的内容,都是需要解决的问题。通过成功实施这一流程,我们不仅验证了LLM与Web爬虫结合的有效性,还进一步探索了如何通过自动化工具提高研究和分析的效率。
数据加载
通过上面对关键问题的分析,让我们先为即将进行的技术旅程做好准备。从网页内容的加载到信息的转换,再到利用LLM提取关键数据,都是构建有效网络研究工具的关键环节。
首先,我们将面对的挑战是如何高效地加载网页内容。异步HTML加载器(AsyncHtmlLoader)扮演着至关重要的角色。使用aiohttp库构建的AsyncHtmlLoader能够进行异步HTTP请求,非常适合于简单轻量级的网页抓取工作。这意味着它能够同时处理多个URL的请求,提高了数据抓取的效率,特别是当我们需要从多个网站快速获取信息时。
对于那些更复杂的网站,其中的内容可能依赖于JavaScript渲染,我们可能需要更强大的工具,例如AsyncChromiumLoader。这个加载器利用Playwright来启动一个Chromium实例,它不仅可以处理JavaScript渲染,还可以应对更复杂的Web交互。Playwright是一个强大的库,支持多种浏览器自动化操作,其中Chromium就是一个被广泛支持的浏览器。
Chromium可以在无头模式下运行,即没有图形用户界面的浏览器,这在网页抓取中很常见。在无头模式下,浏览器后台运行,执行自动化任务,而用户不会看到任何的浏览器窗口。这样的操作对于服务器端的抓取任务尤其有用,因为它们可以模拟浏览器中的完整用户交互过程,而不需要实际显示界面。
无头模式,或称为“无界面模式”,是一种在不打开图形界面的情况下运行应用程序的方式。想象一下,你的电脑在执行一些任务,如下载文件、刷新数据或运行一个复杂的计算过程,而这一切都在没有打开任何窗口的情况下静静进行。这正是无头模式的工作原理。
在Web开发和自动化测试领域,无头模式尤为有用。例如,开发者可能需要测试一个网页在不同浏览器中的表现,但并不需要真正地视觉上检查这些网页,而是要检查代码的运行结果。在这种情况下,他们可以使用无头模式的浏览器来模拟用户的行为,如点击链接、填写表单等,同时浏览器本身不会在屏幕上显示。
实际上,我们介绍了AsyncHtmlLoader和AsyncChromiumLoader两种加载器,本例中我们使用前者就足够了,其示例代码如下:
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内容中提取特定信息的场景来说非常适合。例如,如果我们需要从一个新闻网站中提取文章标题和摘要,而这些内容是通过`<span>`标签来标识的,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文档。在这个例子中,我们特别关注于`<span>`标签,因为我们假设这些标签包含了新闻文章的标题和摘要信息。
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年分布式架构经验。