Dify + Firecrawl + LLMで自動スクレイピング

# はじめに
:::note
この記事は、モチベーションクラウドシリーズアドベントカレンダー2024の記事です。
:::
https://qiita.com/advent-calendar/2024/lmi

今回はDifyというツールを使ってWebスクレイピングとLLMを組み合わせたワークフローを簡単に作ってみました。
その概要をご紹介します。

:::note warn
※ Webスクレイピングは規約や負荷に配慮、注意して行いましょう
:::


# Difyとは

https://dify.ai/jp

**Difyは、オープンソースのAIアプリ開発プラットフォームです。**
AIを用いたワークフローを作成することができ、LLMOpsを簡単かつ効果的に構築できます。

また、ブロックプログラミングのようにブロックとブロックを組み合わせることで簡単にワークフローを創ることのできるUIを提供しており、開発者もそうでない人も問わず使用することができます。


# 今回作成したもの
対象のWEBページに対し


1. **スクレイピングで抽出**

2. **記事の要約を出力**

を行うワークフローを構築しました

## 概要

今回構築したのは、以下のようなワークフローです
![スクリーンショット 2024-12-05 16.36.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2327046/7605d47b-379e-67e3-8f89-8398c4b1f6fc.png)

1. **開始**
2. **Webページのスクレイピング**
    * Firecrawlを用いて対象ページのデータを取得します
3. **記事内容の要約**
    * LLMを活用して、スクレイピングデータを解釈し、要約を生成します
4. **終了**

### フローの入力値
今回対象ページとして、Viteのドキュメントを対象にしました

**▼ 対象**

https://ja.vite.dev/guide/


### フローの出力値
ページの要約を行い、最終的に下記の文面を出力します

```
<3行サマリー>
* Viteは現代のWebプロジェクト向けの高速なビルドツールです。
* 開発サーバーとRollupを使用したビルドコマンドを提供し、簡単にプロジェクトを開始できます。
* さまざまなフレームワークやテンプレートをサポートし、コミュニティによる拡張も可能です。

<要約>
Viteは、現代のWeb開発において迅速で効率的な開発体験を提供するために設計されたビルドツールです。主に、高速なHot Module Replacement (HMR)を含む開発サーバーと、Rollupによるコードバンドルのビルドコマンドから成り立っています。Viteは、実用的なデフォルト設定を提供し、さまざまなフレームワークやツールと統合できるプラグインシステムを備えています。

Viteは最新のブラウザを対象にしており、そのためシンタックスの低下を防ぎます。オンラインでの試用も可能で、異なるテンプレートを簡単に選択できます。プロジェクトの生成は、コマンドラインから簡単に行え、必要に応じて手動インストールやコミュニティー提供のテンプレートも利用できます。開発サーバーはプロジェクトルートに基づいて起動し、複数のエントリーポイントを持つマルチページアプリにも対応しています。

Viteは高い拡張性を持ち、コミュニティによるサポートも充実しているため、開発者は質問やサポートを容易に受けることができます。
```


### 実行イメージ

![名称未設定 (5) (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2327046/b29018aa-a803-9c91-9674-43903dd9cd1f.gif)



# ワークフロー詳細
## ① FirecrawlによるWebスクレイピング
DifyではFirecrawlツールを用い、外部ページのデータを収集することができます。
LLMが学習しやすい形の整形に特化したツールです。ありがたい。

https://www.firecrawl.dev/

今回の設定は下記です
### 設定詳細
**ブロック追加 > ツール > FireCrawl > Scrapeブロックを選択**
![スクリーンショット 2024-12-05 16.41.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2327046/54fe1f7e-ff54-ddc9-9e28-d871efc79afc.png)


**▼ ブロックでの入力変数**
| 変数名 | 概要 | 今回の設定 |
|:----------|:--------|:-------|
| `URL` | ・対象ページのURL。 <br/>・固定値でも変数による指定も可能 | https://www.firecrawl.dev/ |
| `ONLY MAIN CONTENT` | ・mainコンテンツのみを返却するか否かを指定します<br/>  ・ヘッダーフッターやナビゲーションなどはここで排除してくれます | True |
| `INCLUDED TAGS` | ・スクレイピングで取得するタグを指定することができます<br/> ・id指定やclass指定も可能です | （特に無し） |

HTMLの構造さえ整っていれば、`ONLY MAIN CONTENT`をtrueにするだけで十分でした。便利。

## ② LLMによる解釈・要約

①のアウトプットの返却値に対し、LLMを通して文面を解釈・要約します

### 設定詳細
**ブロック追加 > ブロック > LLMブロックを選択**
![スクリーンショット 2024-12-05 16.46.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2327046/b029e14c-c7b2-431b-b8f4-f794286c1d6b.png)


**▼ ブロックでの入力変数**
| 変数名 | 概要 |
|:------------|:--------|
| モデル | ・使用するLLMモデルを選択します|
| コンテキスト | ・プロンプトの中で使用する変数を選択しておきます|
| SYSTEM | ・プロンプトを指定します。コンテキストで指定した変数をここで利用することができます|

今回の処理で使用したプロンプトは下記です。
```
# 命令概要
あなたはプロの編集者です。
いまからある記事をお伝えするので、わかりやすい要約文を作成してください。
ただし以下の条件すべてを満たすものとします。

・最初に、この記事のようやくを3行で記載する
・その後、詳細の要約文を作成する
・日本語で出力を行う

# 出力
<3行サマリー>
* ~~~
* ~~~
* ~~~

<要約>
~~~~~~~
~~~~~~~
~~~~~~~

では始めてください。

# 要約対象
{x}Scrape/{x}text ※ コンテキストで使用した変数です
```

## ③ 終了と実行
**ブロック追加 > ブロック > 終了ブロックを選択**
各ブロックをワークフローとしてつなぎ、右上の **「▷実行」** ボタンを押下してフローを実行します

これで、今回のフロー構築は終了です。

# まとめ
**LLMを使用したツール作成も、スクレイピングに関しても、簡単に構築することができ、DifyやFirecrawlの使い勝手の良さを改めて実感しました。**
スクレイピング結果に対して、要素をXPathなどで抽出したり、HTMLタグを消したりと、実コードでの処理が必要だろうと試行錯誤してましたが、Firecrawlがその全てを自動で巻き取ってくれたのでだいぶ便利でした。こうした部分をツールが吸収してくれることで、開発者は本来注力すべきフローの構築に集中できそうです。

最後までお読みいただき、ありがとうございました。