Webスクレイピング×LangChainで競合調査を自動化する:BeautifulSoupとPlaywrightの実戦投入
はじめに:「ググってまとめといて」業務を撲滅したい
企画部門やマーケティングチームから、「競合他社のこの製品のスペック、一覧表にしてくれない?」みたいな依頼、来ませんか?
最初は手作業でコピペしていても、10件目くらいで「俺の時給を使ってやることか?」と虚無感に襲われます。
こういう単純作業こそ、AIとスクレイピングの出番です。今回はLangChainを使って、URLを渡すだけでWebサイトの内容を引っこ抜き、さらにAIに「要するにどういうこと?」と要約させる自動化フローを紹介します。
基礎知識:LangChainにおけるWebLoaderの仕組み
LangChainには document_loaders
という便利なモジュール群があり、その中にWebサイト読み込み用のクラスが用意されています。これらは単にHTMLを取得するだけでなく、メインコンテンツの抽出(不要なヘッダーや広告の削除)まで考慮されているのが特徴です。
昔ながらの BeautifulSoup
をガリガリ書くのも楽しいですが、LangChainのLoaderを使えば、取得したテキストをそのままLLMに突っ込んで解析できるので、開発スピードが段違いです。
実装・設定:静的サイト(BS4)と動的サイト(Playwright)の使い分け
Webサイトには2種類あります。単純なHTMLでできている「静的サイト」と、JavaScriptで動的に描画される「動的サイト」です。
パターンA:静的サイトなら軽量な WebBaseLoader
ニュースサイトやブログなど、シンプルな構造ならこれで十分です。依存ライブラリも少なく、動作も早いです。
from langchain_community.document_loaders import WebBaseLoader
loader = WebBaseLoader("https://example.com/product/spec")
documents = loader.load()
パターンB:動的サイトなら Playwright
最近のサイトは多くがSPA(Single Page Application)です。これらはブラウザで表示しないと中身が取れません。そこで AsyncChromiumLoader
(Playwright) を使います。
from langchain_community.document_loaders import AsyncChromiumLoader
from langchain_community.document_transformers import BeautifulSoupTransformer
# ヘッドレスブラウザでアクセス
loader = AsyncChromiumLoader(["https://example.com/spa-page"])
html = loader.load()
# 必要なタグだけ抽出(トークン節約のため重要!)
bs_transformer = BeautifulSoupTransformer()
docs_transformed = bs_transformer.transform_documents(html, tags_to_extract=["h2", "p", "table"])
応用テクニック:取得データの整形と要約
スクレイピングした直後のデータはノイズだらけです。そのままLLMに投げると精度が落ちます。
そこで、私はよく「抽出スキーマ」を定義します。「製品名」「価格」「特徴」というJSONフォーマットを指定して、LLMにそこだけ埋めさせるのです。これで、ごちゃごちゃしたHTMLが綺麗なデータベースに早変わりします。
トラブルシューティング:アクセス拒否とIPブロックの壁
スクレイピングには 403 Forbidden がつきものです。
User-Agentの偽装
は基本ですが、それでもダメな時は「アクセス頻度を下げる(sleepを入れる)」のが一番です。我々の目的はDDoS攻撃ではありません。「人間がゆっくり見ている」フリをさせてください。
まとめ:情報は「探す」時代から「集まってくる」時代へ
Webスクレイピングをマスターすれば、毎朝特定のニュースサイトを巡回して、「自社に関係あるトピック」だけをSlackに通知するボットなんかも作れます。
人間が情報を探しに行くのではなく、エージェントが情報を集めてきてくれる仕組みを作る。これもエンジニアの重要な仕事の一つですね。
コメント
コメントを投稿