文章目录
- AI(学习笔记第五课) 使用langchain进行AI开发 load documents(web)
- 学习内容:
- 1.load documents(web)
- 1.1 学习`url`
- 1.2 提前安装`python`的`package`
- 1.2 使用`WebBaseLoader`进行`webpage`的`load`
- 1.3 使用`BeautifulSoup4`进行`webpage`的部分截取
- 1.4 使用`UnstructuredURLLoader`的部分截取
- 1.5 使用`UnstructuredULoader`的截取父子关系的节点
- 1.5.1 使用时候的注意点
- 1.5.2 代码解析
- 1.5.3 代码执行
- 2. 使用定位结果进行检索`Vector search over page content`
- 2.1 最终代码
- 2.2 执行结果
AI(学习笔记第五课) 使用langchain进行AI开发 load documents(web)
- 使用
langchain如何解析web page - 使用
vector_store对search的docs进行ai检索
学习内容:
- 从
webpage中构建vector store,并使用进行检索
1.load documents(web)
1.1 学习url
langchain的load documents(web)文档。
1.2 提前安装python的package
langchain-community
beautifulsoup4
langchain_core
1.2 使用WebBaseLoader进行webpage的load
import asyncio
import bs4,os
from langchain_community.document_loaders import WebBaseLoader, UnstructuredURLLoader
from typing import List
from langchain_core.documents import Document
page_url = "https://python.langchain.com/docs/how_to/chatbots_memory/"
# 设置USER_AGENT避免警告
os.environ["USER_AGENT"] = "MyApp/1.0"
async def load_whole_web():loader = WebBaseLoader(web_paths=[page_url])pages = []async for page in loader.alazy_load():pages.append(page)print(f"{pages[0].metadata}\n")print(pages[0].page_content[:500].strip())asyncio.run(load_whole_web())
这里,使用WebBaseLoader对代码对指定的webpage进行load到pages变量中,之后使用metadata和page_content进行输出。
metadata输出如下json

1.3 使用BeautifulSoup4进行webpage的部分截取
实际上,很可能需要对特定的<div>或者特定的class,来对特定的webpage部分进行截取。
async def load_partial_web():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) == 1doc = docs[0]print(f"{doc.metadata}\n")print(doc.page_content[:500])print(doc.page_content[-500:])
asyncio.run(load_partial_web())

这样保证,截取的是<div class="theme-doc-markdown markdown">的部分。

1.4 使用UnstructuredURLLoader的部分截取
和pdf的loader一样,想要对内容进行洗的切分,可以使用UnstructuredURLLoader。
注意,这里练习时候使用的UnstructuredURLLoader的版本较低,对示例的代码进行了调整。
async def load_web_with_unstructured():loader = UnstructuredURLLoader(urls=[page_url], # 替换为实际URLmode="elements",strategy='fast')docs = []async for doc in loader.alazy_load():docs.append(doc)for doc in docs[:5]:print(f'{doc.metadata["category"]}: {doc.page_content}')return docsasyncio.run(load_web_with_unstructured())
可以看出,这里将web内容解析到doc中,保存起来,并将前5个doc进行category和page_content进行打印。

1.5 使用UnstructuredULoader的截取父子关系的节点
1.5.1 使用时候的注意点
这里需要注意两点:
- 不是
from langchain_community.document_loader的UnstructuredURLLoader,这里需要换成from langchain_unstructure的UnstructuredLoader` langchain_unstructured的包,版本需要>=0.1.5
1.5.2 代码解析
import asyncio
import bs4,os
from langchain_community.document_loaders import WebBaseLoader,UnstructuredURLLoader
from langchain_unstructured import UnstructuredLoader
from typing import List
from langchain_core.documents import Document
async def get_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)for doc in setup_docs[:3]:print(f'{doc.metadata["category"]}: {doc.page_content}')return setup_docsasync def _get_setup_docs_from_url(url: str) -> List[Document]:loader = UnstructuredLoader(web_url=url)setup_docs = []parent_id = -1async for doc in loader.alazy_load():metadata = doc.metadataif metadata.get("category") == "Title" and doc.page_content.startswith("Setup"):parent_id = metadata.get("element_id")if metadata.get("parent_id") == parent_id:setup_docs.append(doc)return setup_docsasyncio.run(get_setup_docs())
这里,可以看出是定位到category==Title并且startWith(Setup)的部分,之后记录下parent_id,之后接下来便利其他doc,如果parent_id是上面记录的parent_id那么就将该doc都作为setup的说明文档,保存起来。
1.5.3 代码执行

2. 使用定位结果进行检索Vector search over page content
2.1 最终代码
import asyncio
import bs4,os
from langchain_community.document_loaders import WebBaseLoader,UnstructuredURLLoader
from langchain_unstructured import UnstructuredLoader
from typing import List
from langchain_core.documents import Document
from langchain_ollama.embeddings import OllamaEmbeddings
from langchain_core.vectorstores import InMemoryVectorStorepage_url = "https://python.langchain.com/docs/how_to/chatbots_memory/"
# 设置USER_AGENT避免警告
os.environ["USER_AGENT"] = "MyApp/1.0"# 替换 OpenAIEmbeddings 配置为 Ollama 本地模型
embeddings = OllamaEmbeddings(model="nomic-embed-text", # 或其他支持的本地模型如 "mistral", "nomic-embed-text"base_url="http://192.168.2.208:11434" # Ollama 默认地址
)
async def _get_setup_docs() -> List[Document]: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)return setup_docsasync def _get_setup_docs_from_url(url: str) -> List[Document]:loader = UnstructuredLoader(web_url=url)setup_docs = []parent_id = -1async for doc in loader.alazy_load():metadata = doc.metadataif metadata.get("category") == "Title" and doc.page_content.startswith("Setup"):parent_id = metadata.get("element_id")if metadata.get("parent_id") == parent_id:setup_docs.append(doc)return setup_docsasync def search_vector_store():setup_docs =await _get_setup_docs()vector_store = InMemoryVectorStore.from_documents(setup_docs, embeddings)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')asyncio.run(search_vector_store())
这里看出,使用本地构建的ollama模型nomic-embed-text,进行ai的检索。
2.2 执行结果

基于webpage,ai大模型给出了检索结果。