Skip to main content
Open In ColabOpen on GitHub

如何加载网页

本指南介绍如何将网页加载到我们后续使用的 LangChain Document 格式中。网页包含文本、图像和其他多媒体元素,通常以 HTML 表示。它们可能包含指向其他页面或资源的链接。

LangChain 与多种适用于网页的解析器集成。合适的解析器取决于您的具体需求。以下是两种可能的示例:

  • 简单快速 的解析,我们从每个网页中恢复一个 Document,其内容以“扁平化”字符串形式表示;
  • 高级 解析,其中我们每页恢复多个 Document 对象,从而能够识别和遍历章节、链接、表格及其他结构。

设置

对于“简单快速”的解析,我们需要 langchain-communitybeautifulsoup4 库:

%pip install -qU langchain-community beautifulsoup4

对于高级解析,我们将使用 langchain-unstructured

%pip install -qU langchain-unstructured

简单快速的文本提取

如果您正在寻找一种嵌入网页中的文本的简单字符串表示形式,下面的方法是合适的。它将返回一个包含 Document 对象的列表——每页一个——其中包含页面文本的单个字符串。其底层使用了 beautifulsoup4 Python 库。

LangChain 文档加载器实现 lazy_load 及其异步变体 alazy_load,它们返回 Document objects 的迭代器。我们将在下面使用这些功能。

import bs4
from langchain_community.document_loaders import WebBaseLoader

page_url = "https://python.langchain.com/docs/how_to/chatbots_memory/"

loader = WebBaseLoader(web_paths=[page_url])
docs = []
async for doc in loader.alazy_load():
docs.append(doc)

assert len(docs) == 1
doc = docs[0]
API 参考:WebBaseLoader
USER_AGENT environment variable not set, consider setting it to identify your requests.
print(f"{doc.metadata}\n")
print(doc.page_content[:500].strip())
{'source': 'https://python.langchain.com/docs/how_to/chatbots_memory/', 'title': 'How to add memory to chatbots | \uf8ffü¶úÔ∏è\uf8ffüîó LangChain', 'description': 'A key feature of chatbots is their ability to use content of previous conversation turns as context. This state management can take several forms, including:', 'language': 'en'}

How to add memory to chatbots | 🦜️🔗 LangChain







Skip to main contentShare your thoughts on AI agents. Take the 3-min survey.IntegrationsAPI ReferenceMoreContributingPeopleLangSmithLangGraphLangChain HubLangChain JS/TSv0.3v0.3v0.2v0.1💬SearchIntroductionTutorialsBuild a Question Answering application over a Graph DatabaseTutorialsBuild a Simple LLM Application with LCELBuild a Query Analysis SystemBuild a ChatbotConversational RAGBuild an Extraction ChainBuild an AgentTaggingd

这基本上是页面HTML中文本的转储。它可能包含多余的资讯,如标题和导航栏。如果您熟悉预期的HTML,可以通过BeautifulSoup指定所需的 <div> 类和其他参数。以下是仅解析文章正文内容:

loader = WebBaseLoader(
web_paths=[page_url],
bs_kwargs={
"parse_only": bs4.SoupStrainer(class_="theme-doc-markdown markdown"),
},
bs_get_text_kwargs={"separator": " | ", "strip": True},
)

docs = []
async for doc in loader.alazy_load():
docs.append(doc)

assert len(docs) == 1
doc = docs[0]
print(f"{doc.metadata}\n")
print(doc.page_content[:500])
{'source': 'https://python.langchain.com/docs/how_to/chatbots_memory/'}

How to add memory to chatbots | A key feature of chatbots is their ability to use content of previous conversation turns as context. This state management can take several forms, including: | Simply stuffing previous messages into a chat model prompt. | The above, but trimming old messages to reduce the amount of distracting information the model has to deal with. | More complex modifications like synthesizing summaries for long running conversations. | We'll go into more detail on a few techniq
print(doc.page_content[-500:])
a greeting. Nemo then asks the AI how it is doing, and the AI responds that it is fine.'), | HumanMessage(content='What did I say my name was?'), | AIMessage(content='You introduced yourself as Nemo. How can I assist you today, Nemo?')] | Note that invoking the chain again will generate another summary generated from the initial summary plus new messages and so on. You could also design a hybrid approach where a certain number of messages are retained in chat history while others are summarized.

请注意,这需要提前具备关于正文内容在底层 HTML 中如何表示的技术知识。

我们可以使用多种设置对 WebBaseLoader 进行参数化,以指定请求头、速率限制、解析器以及其他用于 BeautifulSoup 的关键字参数。详细信息请参阅其 API 参考

高级解析

如果需要对页面内容进行更细粒度的控制或处理,此方法是合适的。如下所示,我们不再为每页生成一个Document并使用BeautifulSoup来控制其内容,而是生成多个Document对象,代表页面上的不同结构。这些结构可以包括章节标题及其对应正文、列表或枚举、表格等。

其内部使用了 langchain-unstructured 库。有关将 Unstructured 与 LangChain 集成的更多信息,请参阅 集成文档

from langchain_unstructured import UnstructuredLoader

page_url = "https://python.langchain.com/docs/how_to/chatbots_memory/"
loader = UnstructuredLoader(web_url=page_url)

docs = []
async for doc in loader.alazy_load():
docs.append(doc)
API 参考:UnstructuredLoader
INFO: Note: NumExpr detected 12 cores but "NUMEXPR_MAX_THREADS" not set, so enforcing safe limit of 8.
INFO: NumExpr defaulting to 8 threads.

请注意,在不了解页面HTML结构的情况下,我们仍能恢复正文内容的自然组织:

for doc in docs[:5]:
print(doc.page_content)
How to add memory to chatbots
A key feature of chatbots is their ability to use content of previous conversation turns as context. This state management can take several forms, including:
Simply stuffing previous messages into a chat model prompt.
The above, but trimming old messages to reduce the amount of distracting information the model has to deal with.
More complex modifications like synthesizing summaries for long running conversations.
ERROR! Session/line number was not unique in database. History logging moved to new session 2747

从特定部分提取内容

每个 Document 对象代表页面的一个元素。其元数据包含有用的信息,例如其类别:

for doc in docs[:5]:
print(f'{doc.metadata["category"]}: {doc.page_content}')
Title: How to add memory to chatbots
NarrativeText: A key feature of chatbots is their ability to use content of previous conversation turns as context. This state management can take several forms, including:
ListItem: Simply stuffing previous messages into a chat model prompt.
ListItem: The above, but trimming old messages to reduce the amount of distracting information the model has to deal with.
ListItem: More complex modifications like synthesizing summaries for long running conversations.

元素之间也可能存在父子关系——例如,一个段落可能属于一个带有标题的章节。如果某个章节特别重要(例如,用于索引),我们可以隔离相应的 Document 对象。

例如,下面我们将加载两个网页“设置”部分的内容:

from typing import List

from langchain_core.documents import Document


async def _get_setup_docs_from_url(url: str) -> List[Document]:
loader = UnstructuredLoader(web_url=url)

setup_docs = []
parent_id = -1
async for doc in loader.alazy_load():
if doc.metadata["category"] == "Title" and doc.page_content.startswith("Setup"):
parent_id = doc.metadata["element_id"]
if doc.metadata.get("parent_id") == parent_id:
setup_docs.append(doc)

return setup_docs


page_urls = [
"https://python.langchain.com/docs/how_to/chatbots_memory/",
"https://python.langchain.com/docs/how_to/chatbots_tools/",
]
setup_docs = []
for url in page_urls:
page_setup_docs = await _get_setup_docs_from_url(url)
setup_docs.extend(page_setup_docs)
API 参考:文档
from collections import defaultdict

setup_text = defaultdict(str)

for doc in setup_docs:
url = doc.metadata["url"]
setup_text[url] += f"{doc.page_content}\n"

dict(setup_text)
{'https://python.langchain.com/docs/how_to/chatbots_memory/': "You'll need to install a few packages, and have your OpenAI API key set as an environment variable named OPENAI_API_KEY:\n%pip install --upgrade --quiet langchain langchain-openai\n\n# Set env var OPENAI_API_KEY or load from a .env file:\nimport dotenv\n\ndotenv.load_dotenv()\n[33mWARNING: You are using pip version 22.0.4; however, version 23.3.2 is available.\nYou should consider upgrading via the '/Users/jacoblee/.pyenv/versions/3.10.5/bin/python -m pip install --upgrade pip' command.[0m[33m\n[0mNote: you may need to restart the kernel to use updated packages.\n",
'https://python.langchain.com/docs/how_to/chatbots_tools/': "For this guide, we'll be using a tool calling agent with a single tool for searching the web. The default will be powered by Tavily, but you can switch it out for any similar tool. The rest of this section will assume you're using Tavily.\nYou'll need to sign up for an account on the Tavily website, and install the following packages:\n%pip install --upgrade --quiet langchain-community langchain-openai tavily-python\n\n# Set env var OPENAI_API_KEY or load from a .env file:\nimport dotenv\n\ndotenv.load_dotenv()\nYou will also need your OpenAI key set as OPENAI_API_KEY and your Tavily API key set as TAVILY_API_KEY.\n"}

页面内容的向量搜索

将页面内容加载到 LangChain Document 对象后,我们可以以常规方式对其进行索引(例如用于 RAG 应用)。以下我们使用 OpenAI 嵌入,但任何 LangChain 嵌入模型均可。

%pip install -qU langchain-openai
import getpass
import os

if "OPENAI_API_KEY" not in os.environ:
os.environ["OPENAI_API_KEY"] = getpass.getpass("OpenAI API Key:")
from langchain_core.vectorstores import InMemoryVectorStore
from langchain_openai import OpenAIEmbeddings

vector_store = InMemoryVectorStore.from_documents(setup_docs, OpenAIEmbeddings())
retrieved_docs = vector_store.similarity_search("Install Tavily", k=2)
for doc in retrieved_docs:
print(f'Page {doc.metadata["url"]}: {doc.page_content[:300]}\n')
INFO: HTTP Request: POST https://api.openai.com/v1/embeddings "HTTP/1.1 200 OK"
INFO: HTTP Request: POST https://api.openai.com/v1/embeddings "HTTP/1.1 200 OK"
``````output
Page https://python.langchain.com/docs/how_to/chatbots_tools/: You'll need to sign up for an account on the Tavily website, and install the following packages:

Page https://python.langchain.com/docs/how_to/chatbots_tools/: For this guide, we'll be using a tool calling agent with a single tool for searching the web. The default will be powered by Tavily, but you can switch it out for any similar tool. The rest of this section will assume you're using Tavily.

其他网页加载器

有关可用的LangChain网页加载器的列表,请参见 此表格