支持私有化部署
AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


跨网页解析实战:基于LangChain的多段文本分析与结构化抽取

发布日期:2025-05-10 22:37:50 浏览次数: 1518 作者:机智流
推荐语

掌握网页内容解析,提升文本分析能力。

核心内容:
1. 使用LangChain从网页提取概要、关键词等基础信息
2. 结构化抽取网页中的参考文献信息
3. 处理长文档,实现多段文本的高效分析

杨芳贤
53A创始人/腾讯云(TVP)最具价值专家

作者:李剑锋

前言

继上节课我们学习了如何利用 Function Calling 完成文本标注和信息抽取任务后,本节课将围绕“从真实网页中提取结构化信息”的主题展开一次完整实战。课程分为以下三个模块:

  • 模块一:基础抽取任务 —— 我们将学习如何从整篇网页中提取概要、关键词和语言等基础信息;
  • 模块二:结构化文献信息识别 —— 解析网页中的参考文献,抽取其标题与作者等关键字段;
  • 模块三:大文本处理与多段抽取 —— 结合文本分段与 map 操作,实现对长文档的高效批量分析。

本节课将使用 LangChain 的 WebBaseLoader 获取网页内容,结合 Function Calling 与多段映射机制(如 Runnable.map),帮助我们构建一个具备真实网页理解能力的智能文本分析链。

加载网页内容

首先,我们需要先从网络上获取一部分我们需要解析的内容。我们通过 from langchain_community.document_loaders import WebBaseLoader 导入网页加载器 WebBaseLoader,该加载器可以将网页作为文档加载到 LangChain 中。接着,使用 WebBaseLoader(url) 创建加载器对象,并传入目标网页的链接。在调用 loader.load() 后,网页内容会被下载并封装为一个 Document 对象列表。

我们取出第一个文档 doc = documents[0],并从中获取其文本内容字段 page_content。为了限制处理文本的长度,我们只截取了前10000个字符用于分析。最后,通过 print(page_content[:1000]) 将文本的前1000个字符打印出来,方便我们预览内容是否加载成功。

from langchain_community.document_loaders import WebBaseLoader
loader = WebBaseLoader("https://lilianweng.github.io/posts/2023-06-23-Agent/")
documents = loader.load()
doc = documents[0]
page_content = doc.page_content[:10000]
print(page_content[:1000])

基本抽取:概要、语言、关键词

在成功加载了网页的内容后,我们并不能直接使用这些原始文本作为智能系统的输入。为了便于后续处理、分析和展示,我们需要对网页中大量的文本信息进行结构化抽取,提取出如“摘要、语言、关键词”等基础信息。这不仅有助于快速理解文本核心内容,也为后续文献信息提取、内容索引构建等任务打下基础。

定义数据结构

首先,我们使用 Pydantic 来定义一个结构化的 Python 类 概览信息,表示模型需要从文本中抽取的三个字段:摘要语言关键词。每个字段都通过 Field 添加了中文描述,便于大模型理解:

from pydantic import BaseModel, Field
class 概览信息(BaseModel):
    摘要: str = Field(description="请提供对该段内容的简要总结")
    语言: str = Field(description="请说明该段内容使用的语言(例如 zh、en)")
    关键词: str = Field(description="请提取该段内容的核心关键词")

转换为函数格式

使用 LangChain 提供的工具将该数据结构转换为 OpenAI Function Calling 格式,方便模型输出结构化 JSON:

from langchain_core.utils.function_calling import convert_to_openai_function
overview_tagging_function = [convert_to_openai_function(概览信息)]

构造提示词模板

我们使用 ChatPromptTemplate 定义交互提示,指导模型根据输入提取所需信息:

from langchain.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_messages([
    ("system""请从给定文本中提取摘要、语言和关键词"),
    ("human""{input}")
])

模型加载与函数绑定

然后,加载大语言模型(如 qwen-turbo),并将抽取函数绑定到模型,确保其生成符合结构定义的调用结果:

from langchain_openai import ChatOpenAI
model = ChatOpenAI(
    model="qwen-turbo",
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    api_key="sk-你的api-key"
)

model_with_functions = model.bind(
    functions=overview_tagging_function,
    function_call={"name""概览信息"}  # 与类名保持一致
)

构建链条并执行调用

我们将提示词、模型、输出解析器串联成一个处理链 tagging_chain,并传入网页内容进行抽取:

from langchain.output_parsers.openai_functions import JsonOutputFunctionsParser
tagging_chain = prompt | model_with_functions | JsonOutputFunctionsParser()
print(tagging_chain.invoke({"input": page_content}))

✅ 输出示例

{
  "摘要""本文综述了基于大型语言模型(LLM)的自主代理系统的组成和功能,包括规划、记忆和工具使用,并探讨了反思在提升代理性能中的作用。",
  "语言""zh",
  "关键词""LLM, 自主代理系统, 规划, 记忆, 工具使用, 反思"
}

该输出说明模型已正确识别网页内容的语言、生成了简洁的摘要,并提取出核心关键词,结构清晰,适合后续整理与展示。

这部分完整代码如下所示:

from pydantic import BaseModel, Field
from langchain.output_parsers.openai_functions import JsonOutputFunctionsParser
from langchain.prompts import ChatPromptTemplate
from langchain_core.utils.function_calling import convert_to_openai_function
from langchain_openai import ChatOpenAI
from langchain_community.document_loaders import WebBaseLoader

# 0. 文件提取
loader = WebBaseLoader("https://lilianweng.github.io/posts/2023-06-23-agent/")
documents = loader.load()
doc = documents[0]
page_content = doc.page_content[:10000]
print(page_content[:1000])

# 1. 定义数据结构(用于生成函数格式)
class 概览信息(BaseModel):
    摘要: str = Field(description="请提供对该段内容的简要总结")
    语言: str = Field(description="请说明该段内容使用的语言(例如 zh、en)")
    关键词: str = Field(description="请提取该段内容的核心关键词")

# 2. 转换为 OpenAI 可识别的函数定义
overview_tagging_function = [convert_to_openai_function(概览信息)]

# 3. 构造提示词模板
prompt = ChatPromptTemplate.from_messages([
    ("system""请从给定文本中提取摘要、语言和关键词"),
    ("human""{input}")
])

# 4. 模型设置
model = ChatOpenAI(
    model="qwen-turbo",
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    api_key="sk-0"# 你的 API key
)

# 5. 绑定函数调用
model_with_functions = model.bind(
    functions=overview_tagging_function,
    function_call={"name""概览信息"}  # 与类名保持一致
)

# 6. 构建链条 + 执行调用
tagging_chain = prompt | model_with_functions | JsonOutputFunctionsParser()

# 7. 执行调用并打印结果
print(tagging_chain.invoke({"input": page_content}))

文献抽取:标题与作者

在完成基础信息抽取后,我们可以用类似的方法进一步对网页中的引用信息进行结构化分析。很多技术类博客或论文页面通常会在正文或结尾部分提及多个参考文献,我们希望通过 Function Calling 自动识别出这些文献标题及其作者信息。

定义数据结构

我们通过嵌套结构定义每一篇文献的标题与作者:

class 文献(BaseModel):
    标题: str = Field(description="文献的标题")
    作者: Optional[str] = Field(description="文献作者,可缺失")

class 文献信息(BaseModel):
    文献列表: List[文献] = Field(description="文献信息列表")

转换为函数并绑定模型

使用 convert_to_openai_function 将 Pydantic 数据结构注册为函数定义,并绑定至模型上:

# 2. 转换为大模型可识别的函数定义
paper_extraction_function = [convert_to_openai_function(文献信息)]

# 3. 模型设置
model = ChatOpenAI(
    model="qwen-turbo",
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    api_key="sk-08c1c4ddd292462cb1498189ab5d1224"# 你的 API key
)

# 4. 将函数绑定到模型上
extraction_model = model.bind(
    functions=paper_extraction_function,
    function_call={"name""文献信息"}
)

构造中文提示词模板

我们特别强调不要猜测信息,并要求模型只提取明确提到的文献条目。同时这里也设置了system提示词和human提示词来确保输出的内容符合要求:

# 5. 构造中文提示词模板
prompt = ChatPromptTemplate.from_messages([
    ("system"
     "下面将提供一篇文章,请你从中提取出所有明确提到的参考文献及其作者。\n"
     "不要提取这篇文章本身的标题。\n"
     "如果文章中没有提到任何文献,可以返回一个空列表。\n"
     "不要臆造或猜测信息,只能提取文本中确实提到的内容。"),
    ("human""{input}")
])

构建调用链并执行提取

调用链将模型、提示词和输出解析器组合在一起,指定我们只提取返回字段 文献列表

# 6. 构建调用链并执行
extraction_chain = prompt | extraction_model | JsonKeyOutputFunctionsParser(key_name="文献列表")
print(extraction_chain.invoke({"input": page_content}))

示例输出

[
  {"标题""Chain of thought (CoT)""作者""Wei et al."},
  {"标题""Tree of Thoughts (Yao et al. 2023)""作者""Yao et al."},
  {"标题""LLM+P""作者""Liu et al."},
  {"标题""Chain of Hindsight (CoH)""作者""Liu et al."},
  {"标题""Reflexion""作者""Shinn & Labash"},
  {"标题""Algorithm Distillation (AD)""作者""Laskin et al."}
]

如上所示,大模型可以成功从网页内容中提取出多个参考文献的标题与作者信息,并以统一结构返回结果。

这部分完整的代码如下所示:

from pydantic import BaseModel, Field
from typing import List, Optional
from langchain.output_parsers.openai_functions import JsonKeyOutputFunctionsParser
from langchain.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.utils.function_calling import convert_to_openai_function
from langchain_community.document_loaders import WebBaseLoader

# 0. 文件提取
loader = WebBaseLoader("https://lilianweng.github.io/posts/2023-06-23-agent/")
documents = loader.load()
doc = documents[0]
page_content = doc.page_content[:10000]
print(page_content[:1000])

# 1. 定义数据结构
class 文献(BaseModel):
    标题: str = Field(description="文献的标题")
    作者: Optional[str] = Field(description="文献作者,可缺失")

class 文献信息(BaseModel):
    文献列表: List[文献] = Field(description="文献信息列表")

# 2. 转换为大模型可识别的函数定义
paper_extraction_function = [convert_to_openai_function(文献信息)]

# 3. 模型设置
model = ChatOpenAI(
    model="qwen-turbo",
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    api_key="sk-0"# 你的 API key
)

# 4. 将函数绑定到模型上
extraction_model = model.bind(
    functions=paper_extraction_function,
    function_call={"name""文献信息"}
)

# 5. 构造中文提示词模板
prompt = ChatPromptTemplate.from_messages([
    ("system"
     "下面将提供一篇文章,请你从中提取出所有明确提到的参考文献及其作者。\n"
     "不要提取这篇文章本身的标题。\n"
     "如果文章中没有提到任何文献,可以返回一个空列表。\n"
     "不要臆造或猜测信息,只能提取文本中确实提到的内容。"),
    ("human""{input}")
])

# 6. 构建调用链并执行
extraction_chain = prompt | extraction_model | JsonKeyOutputFunctionsParser(key_name="文献列表")
print(extraction_chain.invoke({"input": page_content}))

多段文本拆分与批量抽取

在上一小节中,我们成功完成了对整篇网页中的文献条目提取。但现实中,网页内容往往冗长,直接交给大模型处理会导致内容超限或信息遗漏。因此我们引入 文本切分 + 映射抽取机制,将原文划分为若干小段后分批处理,提升提取的准确性和稳定性。

文本切分器配置

我们采用 RecursiveCharacterTextSplitter 对网页内容进行递归字符级切分,设置 chunk_overlap=0 表示段落之间不重叠。

from langchain.text_splitter import RecursiveCharacterTextSplitter

text_splitter = RecursiveCharacterTextSplitter(chunk_overlap=0)
splits = text_splitter.split_text(doc.page_content)

切分后内容被保存在 splits 列表中,每一项是一个分段文本,共可得 15 个子段。

构建映射执行链

我们使用 RunnableLambda 构造一个前处理模块,将每一段文本包装成 {"input": ...} 的格式,然后使用 .map() 机制对每段文本应用前面定义的文献抽取链 extraction_chain。所以 prep 的输出是分段后的文本块,每段都被包裹为 input 键值,供模型处理

由于 .map() 的输出是一个“列表的列表”(每段的抽取结果组成一个嵌套结构),因此我们定义了 flatten() 函数来将其扁平化。该函数接受一个二维列表 matrix 作为输入,逐行遍历并将其中每一项扩展加入最终结果,形成一个统一的一维文献条目列表,便于后续处理与展示(如 [[a1, a2], [b1], [c1, c2, c3]])转换成一个统一的平面列表 [a1, a2, b1, c1, c2, c3])。因为后面用 .map() 会对每一段文本单独调用抽取链,每段的结果是一个“列表”,所有段组合起来就成了“列表的列表”。

from langchain.schema.runnable import RunnableLambda

def flatten(matrix):
    flat_list = []
    for row in matrix:
        flat_list += row
    return flat_list

prep = RunnableLambda(
    lambda x: [{"input": doc} for doc in text_splitter.split_text(x)]
)

chain = prep | extraction_chain.map() | flatten
print(chain.invoke(doc.page_content))

✅ 示例输出

执行结果如下,显示模型从不同段落中成功提取出多个真实存在的参考论文及其作者:

[
  {"作者""Wei et al.""标题""Chain of thought (CoT)"},
  {"作者""Yao et al.""标题""Tree of Thoughts (ToT)"},
  {"作者""Liu et al.""标题""LLM+P"},
  {"作者""Shinn & Labash""标题""Reflexion"},
  {"作者""Liu et al.""标题""Chain of Hindsight (CoH)"},
  {"作者""Laskin et al.""标题""Algorithm Distillation (AD)"}
]

此外,还能发现模型提取的参考内容不仅包括正式出版物,也包含网页、项目链接、博客文章等,输出条目总数较多,格式各异。

部分冗余项如 2023、项目地址、非论文条目、重复字段等建议后续通过 去重、合法性过滤与正则匹配 进一步清洗。

完整的代码如下所示:

from pydantic import BaseModel, Field
from typing import List, Optional
from langchain.output_parsers.openai_functions import JsonKeyOutputFunctionsParser
from langchain.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.utils.function_calling import convert_to_openai_function
from langchain_community.document_loaders import WebBaseLoader

# 0. 文件提取
loader = WebBaseLoader("https://lilianweng.github.io/posts/2023-06-23-agent/")
documents = loader.load()
doc = documents[0]
page_content = doc.page_content[:10000]
print(page_content[:1000])

# 1. 定义数据结构
class 文献(BaseModel):
    标题: str = Field(description="文献的标题")
    作者: Optional[str] = Field(description="文献作者,可缺失")

class 文献信息(BaseModel):
    文献列表: List[文献] = Field(description="文献信息列表")

# 2. 转换为大模型可识别的函数定义
paper_extraction_function = [convert_to_openai_function(文献信息)]

# 3. 模型设置
model = ChatOpenAI(
    model="qwen-turbo",
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    api_key="sk-0"# 你的 API key
)

# 4. 将函数绑定到模型上
extraction_model = model.bind(
    functions=paper_extraction_function,
    function_call={"name""文献信息"}
)

# 5. 构造中文提示词模板
prompt = ChatPromptTemplate.from_messages([
    ("system"
     "下面将提供一篇文章,请你从中提取出所有明确提到的参考文献及其作者。\n"
     "不要提取这篇文章本身的标题。\n"
     "如果文章中没有提到任何文献,可以返回一个空列表。\n"
     "不要臆造或猜测信息,只能提取文本中确实提到的内容。"),
    ("human""{input}")
])

# 6. 构建调用链并执行
extraction_chain = prompt | extraction_model | JsonKeyOutputFunctionsParser(key_name="文献列表")
print(extraction_chain.invoke({"input": page_content}))

from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(chunk_overlap=0)
splits = text_splitter.split_text(doc.page_content)
def flatten(matrix):
    flat_list = []
    for row in matrix:
        flat_list += row
    return flat_list

from langchain.schema.runnable import RunnableLambda
prep = RunnableLambda(
    lambda x: [{"input": doc} for doc in text_splitter.split_text(x)]
)
chain = prep | extraction_chain.map() | flatten
print(chain.invoke(doc.page_content))

总结

在本章中,我们系统地实践了如何利用 LangChain 构建一个具备真实网页理解能力的结构化信息抽取链条。整个流程围绕一个实际网页展开,层层递进,涵盖了基础字段抽取、文献信息提取,以及大文本分段处理等关键环节。通过合理设计提示词与结构化数据模型,我们不仅实现了网页内容的精准解析,还借助 .map() 与 flatten() 技术,将长文档切分后逐段提取、再合并为统一结果,有效解决了大语言模型上下文长度限制带来的挑战。

这种“分段处理 + 多段映射 + 统一合并”的机制,为大规模网页、长篇文档、多页 PDF 的智能解析提供了高效、稳定的解决方案。下一步,我们可以在此基础上进一步引入向量检索、知识库构建、语义问答等功能,实现更强大的网页理解与内容服务能力。

-- 完 --


机智流推荐阅读

1. 解锁 LangChain 中的「bind」魔法:打造更聪明的智能应用

2. Manus等一众产品看得眼花缭乱?教你5行代码用LangChain构建AI工作流" data-itemshowtype="0" target="_blank" linktype="text" data-linktype="2">Manus等一众产品看得眼花缭乱?教你5行代码用LangChain构建AI工作流

3. AI开发者必学:一分钟掌握Function Calling的用法与实操

4. 从零开始打造自己的Manus:学学如何使用 LangChain 快速构建 AI Agent

欢迎在“机智流”公众号后台回复“cc”,加入机智流大模型交流群,与我们一起探索 AI 与人类潜能的未来,一起共赴 AI 浪潮!

53AI,企业落地大模型首选服务商

产品:场景落地咨询+大模型应用平台+行业解决方案

承诺:免费场景POC验证,效果验证后签署服务协议。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

添加专属顾问

回到顶部

加载中...

扫码咨询