LangChainには、Webページをドキュメントとして取得する「WebBaseLoader」が用意されています。Webページによっては、WebBaseLoaderで内容が取得できません。
WebBaseLoaderでページを取得してみる
例えば、OpenAI社のNewsのページを取得してみます。
ライブラリーをインストールします。
pip install langchain langchain-community beautifulsoup4
以下のコードを実行します。
import json
import os
os.environ["USER_AGENT"] = (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36"
)
from langchain_community.document_loaders import WebBaseLoader
loader = WebBaseLoader(
web_path="https://openai.com/index/introducing-openai-o1-preview/",
)
documents = loader.load()
for document in documents:
print("--- page_content ---")
print(document.page_content[0:100])
print("-" * 20)
print(json.dumps(document.metadata, indent=2, ensure_ascii=False))
--- page_content ---
Please turn JavaScript on and reload the page.Please enable Cookies and reload the page.
--------------------
{
"source": "https://openai.com/index/introducing-openai-o1-preview/",
"language": "No language found."
}
JavaScriptとクッキーを有効にしてねというメッセージしか取得できませんでした。
HTMLソースを取得し確認すると、「noscript」タグの内容だけが取得できており、ブラウザ上に表示されるコンテンツは取得できませんでした。
このように、WebBaseLoaderではJavaScriptで動的に表示コンテンツを作成しているページはうまく内容を取得できません。
AsyncChromiumLoaderを使う
このような動的なページを取得する際には、「AsyncChromiumLoader」を使うと動作が改善します。
内部でplaywrightを使用しているのでインストールします。
pip install playwright
playwrightに必要なブラウザモジュールをインストールします。
playwright install-deps
playwright install chromium
これで準備が整いました。WebBaseLoaderの代わりにAsyncChromiumLoaderを使用します。
import json
from langchain_community.document_loaders import AsyncChromiumLoader
loader = AsyncChromiumLoader(
urls=["https://openai.com/index/introducing-openai-o1-preview/"],
user_agent="Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Mobile Safari/537.36",
)
documents = loader.load()
for document in documents:
print("--- page_content ---")
print(document.page_content[0:100])
print("-" * 20)
print(json.dumps(document.metadata, indent=2, ensure_ascii=False))
--- page_content ---
<!DOCTYPE html><html lang="en-US" dir="ltr" style="--document-width: 1280px; --gutter-size: max(20px
--------------------
{
"source": "https://openai.com/index/introducing-openai-o1-preview/"
}
WebBaseLoaderでは、HTML内のテキストのみを勝手にパースして取得しますが、AsyncChromiumLoaderはHTML全体が返却されます。
どちらが良いとは言えないですが、WebBaseLoaderと同様の動作にしたい場合は、BeautifulSoupを間に挟むと良いでしょう。
import json
from bs4 import BeautifulSoup
from langchain_community.document_loaders import AsyncChromiumLoader
loader = AsyncChromiumLoader(
urls=["https://openai.com/index/introducing-openai-o1-preview/"],
user_agent="Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Mobile Safari/537.36",
)
documents = loader.load()
def get_text(page_content: str):
soup = BeautifulSoup(page_content, features="html.parser")
return soup.get_text()
for document in documents:
print("--- page_content ---")
print(get_text(document.page_content)[0:100])
print("-" * 20)
print(json.dumps(document.metadata, indent=2, ensure_ascii=False))
--- page_content ---
Introducing OpenAI o1 | OpenAISkip to main contentResearchProductsSafetyCompanyIntroducing OpenAI o1
--------------------
{
"source": "https://openai.com/index/introducing-openai-o1-preview/"
}
いい感じになりました。