FirecrawlでRAG用データ作成を無料でやりたい!(1)構築編
モチベーション
LLMによるRAGシステムを構築するにあたって、検索データの準備は手間がかかります。元となるデータが綺麗な文書ならよいのですが、PDFにせよWebページにせよ、必ずしも綺麗な文書でないことが多いです。最近Web記事などでよく目にするようになった。FireCrawlを使えば、ローカル環境でもWebページから綺麗なマークダウンを生成してくれそうなので、実際にできるか試してみました。
対象読者
RAGやデータセット作成に興味のある人
ローカル環境やオンプレミス環境へのLLMシステムのデプロイに興味がある人
*Dockerをつかったことがある人であればスムーズに読めます
動作環境
- Docker/Docker-composeがインストールされている
- python3/pipがインストールされている(Python 3.11.7/firecrawl-py:1.0.1で試しました)
お試しの方向性
FirecrawlはSaaSが主な提供方法ですが、ローカルでも動作可能です(SaaSでしか提供されない機能も多くあります)。本記事ではDockerコンテナでFirecrawlを構築して、Webサイトからスクレイピング
してみます。
事前準備
スクレイピングはWebサーバに負荷をかける作業であるため、モックとなるWebサイトをローカルに構築します。
よくありそうなページを作ってみました。(画像は用意していないので何も表示されません)
まず、htmlファイルを用意します。
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>サンプルページ</title>
<style>
body {
display: flex;
font-family: Arial, sans-serif;
}
#sidebar {
width: 200px;
background-color: #f4f4f4;
padding: 10px;
}
#content {
flex-grow: 1;
padding: 20px;
}
h1 {
font-size: 24px;
margin-bottom: 10px;
}
ul {
list-style-type: none;
padding: 0;
}
ul li {
margin-bottom: 10px;
}
img {
max-width: 100%;
height: auto;
}
</style>
</head>
<body>
<div id="sidebar">
<h2>目次</h2>
<ul>
<li><a href="sample.html">1. Page 1</a></li>
<li><a href="page2.html">2. Page 2</a></li>
<li><a href="page3.html">3. Page 3</a></li>
</ul>
</div>
<div id="content">
<h1>サンプルページ1</h1>
<p>ここはPage 1の内容(前半)です。</p>
<p>画像をはる場所も用意してみました。</p>
<img src="sample-image.jpg" alt="サンプル画像">
<p>ここはPage 1の内容(後半)です。</p>
</div>
</body>
</html>
次に、適当なディレクトリを作成してindex.htmlを配置し、nginxコンテナから8888ポートで公開します。
docker run -d -p 8888:80 -v </path/to/tekito-na-directory>:/usr/share/nginx/html:ro nginx:alpine
ブラウザから8888ポートにアクセスしてスクリーンショットの画面が表示されればOKです。
Firecrawlコンテナの起動&アクセス確認
Firecrawlコンテナの起動
私は以下の記事を参考に起動しました。
(Difyと繋げている記事が多いですね。)
SDKインストール
Firecrawlには公式のSDKが用意されている。
公式サイトにしたがいインストールする
pip install firecrawl-py
アクセス確認
以下のファイルを実行することでアクセス確認をしてみましょう。
IPアドレス(192.168.1.1)はダミーですので、皆さんの環境にあわせて読み替えてください。
ローカル環境で実行するにはいくつか注意点があります。
from firecrawl import FirecrawlApp
# Create a FirecrawlApp instance
app = FirecrawlApp(api_url="http://localhost:3002",api_key="fc-test",version="v0")
# Scrape a website:
scrape_status = app.scrape_url('http://192.168.1.1:8888')
print(scrape_status['content'])
結果として、以下のような出力が得られるはずです。
index.htmlそのままと比較して、タグなどの情報がそぎ落とされておりすっきりしましたね。
ただ、目次のリンクや画像リンクが含まれています。
RAGのデータソースとしてそのまま使うには、まだ余分なデータが含まれていますね。
$ python scrape.py
目次
--
[1\. Page 1](index.html)
[2\. Page 2](page2.html)
[3\. Page 3](page3.html)
サンプルページ1
========
ここはPage 1の内容(前半)です。
画像をはる場所も用意してみました。
![サンプル画像](http://192.168.1.1:8888/sample-image.jpg)
ここはPage 1の内容(後半)です。
最後に
FireCrawlを使うことで生のHTMLよりもすっきりしたMarkdownが得られました。
しかし、RAGのデータソースとして利用するためにはまだ工夫の余地がありそうです。
次回は、データソースをクレンジングする手法について試してみます。
念のため
- Firecrawlのライセンスは2024.9.6時点でAGPL-3.0 licenseでした。利用にあたってはライセンス条項をご確認ください
Discussion