webアプリ「EChub」の紹介記事【FastAPI/React/AWS/Vercel/Docker/スクレイピング】

# はじめに
当記事では、私が作成したwebアプリ「EChub」について紹介します。
(再投稿です)

# 目次
1. EChubの概要
2. 開発背景
3. 使用技術について
4. スクレイピングについて
5. EChubの課題・改善点

# 1. EChubの概要

**~~以下のURLからアクセスできます~~**
**クローズしています**
[EChub](https://www.echub.net/)

**概要**
複数のECサイト(現時点ではメルカリ・ヤフオク・ペイペイフリマ)の商品をまとめて検索できるというシンプルなアプリケーションです。キーワードを入力することで、バックエンド側が各ECサイトのページをスクレイピングし、商品の情報を表示します。表示された商品の中で興味のあるものをタップすると、その商品のページに飛ぶことができます。
![echub.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332638/9594eb2c-887f-d4c7-cb38-24dacc268d08.gif)

**画面遷移**
* 初期画面
![スクリーンショット 2024-09-15 10.50.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332638/e5538aa2-39a2-b1b8-ba16-19ec545d2af0.png)

* 検索中
![スクリーンショット 2024-09-15 10.50.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332638/7a163c6c-4399-9495-8f1c-aa2efd43d224.png)

* 検索後
![スクリーンショット 2024-09-15 10.51.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332638/be685f7f-0779-7c6d-f251-fa9af36b4995.png)

# 2. EChubの開発背景
私は暇な時についフリマサイトで商品を検索してしまう癖があります。
その際複数のフリマサイトを閲覧するのですが、複数のサイトの商品をまとめて検索・比較できるようになれば便利だなと思い、このアプリの作成に至りました。

# 3. 使用技術について

**使用技術**
* フロントエンド
    * HTML/CSS
    * Javascript
    * React
    * react-bootstrap
    * materialUI
* バックエンド
    * Python 3.9.6
    * FastAPI 0.95.0
* インフラ
    * Docker/Docker-compose
    * AWS EC2
    * Vercel
    * Nginx

**アプリケーション構成図**

![echub.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332638/feafa5d5-be8a-aa7a-336c-f9f199c8001f.png)


**主な技術に関するコメント**
* React
    * 一番メジャーで需要のあるReactを選定
* FastAPI
    * 前提として今まではDjangoでwebアプリの開発を行っていた、このアプリも最初はDjangoで開発していた
    * 開発を進める上で、以下のような理由からFastAPIに変更
        * FastAPIを学ぶコストが低い
        * Djangoよりも非同期通信の実装が簡単であること
        * Djangoよりも処理が早いこと
        * 1つの.pyファイルのみで開発できること
* Docker/Docker-compose
    * 開発当初は学んだことがなく使用しない予定であった
    * EC2にデプロイしようとした際、PythonのPlaywrightというライブラリの依存関係でエラーが発生したため使用
* AWS EC2
    * バックエンドのデプロイ先として利用
    * 以前作成したアプリケーションのデプロイで利用した経験があったため選定
* Vercel
    * フロントエンドのデプロイ先として利用
    * 以下の理由から、フロントエンドのデプロイに適していると感じ選定
        * デプロイプロセスがシンプルで使いやすい
        * 修正後すぐ画面に反映される
        * SSL証明書を自動的に発行してくれる
* Nginx
    * バックエンドのhttps化のために利用

# 4.スクレイピングについて

**スクレイピングとは**
Webスクレイピングとは、ウェブページから情報を抽出し、必要なデータを収集する技術です。スクレイピングは、データマイニングやコンテンツ収集、情報解析などの目的で使用されます。プログラムやツールを使ってウェブページのHTMLやCSSを解析し、特定の要素や属性を取得することでデータを収集します。

**法的に大丈夫か**
今回のアプリケーションにおけるスクレイピングは以下の点から違法性はないと考えています。
* robots.txtにおいてAllowとなってるページをスクレイピングしているため([robots.txtとは](https://developers.google.com/search/docs/crawling-indexing/robots/intro?hl=ja#:~:text=%E3%82%92%E8%A1%8C%E3%81%84%E3%81%BE%E3%81%99%E3%80%82-,robots.,%E3%81%9F%E3%82%81%E3%81%AE%E3%83%A1%E3%82%AB%E3%83%8B%E3%82%BA%E3%83%A0%E3%81%A7%E3%81%AF%E3%81%82%E3%82%8A%E3%81%BE%E3%81%9B%E3%82%93%E3%80%82))
* 一回の商品検索において、検索結果の1ページ目のみスクレイピングを行う設計のため、サーバーにかける負荷が小さいため

**スクレイピングにおいて使用した技術について**
[Playwright(Python版)](https://playwright.dev/python/docs/api/class-playwright)を選びました。
選定理由は、非同期処理に対応しているからです。スクレイピングはI/Oバウンドなタスクであるため、複数のECサイトを同時にスクレイピングすることでパフォーマンスが向上します。このため、非同期処理に対応した関数を使用しました。

# 5.EChubの課題・改善点
以下のような課題・改善点が考えられます。

**検索から表示までの時間の長さ**
EChubの一番の課題点です。
ECサイトの最新の商品情報を取得するために、データベースは利用せず毎回スクレイピングを行っています。そのため、商品を検索してから表示されるまでに10秒近くかかってしまいます。

**ECサイトを増やす**
現時点ではメルカリ・ヤフオク・ペイペイフリマの3つのサイトから情報を取得しています。フリマサイトだけでなく主要なECサイト(Amazon・楽天等)も増やすことが考えられます。(ただし情報を取得するECサイトを増やすと、上記の時間がより長くなってしまいます...)
追記：Amazonや楽天はスクレイピングが禁止されていました

**絞り込み検索**
通常のECサイトにあるような絞り込み検索機能に加えて、どのECサイトから商品情報を取得するか選択するなど機能も考えられます。

**追記：HTMLが変更される度にCSSセレクタを修正しなければいけない**
ECサイトはスクレイピング対策として、定期的にHTMLの構造やclassの属性等が変更されます。変更されると情報を取得できなくなりエラーとなってしまうため、その度に修正しなければいけません。最初にこの記事を書いてから2回もスクレイピング部分を修正しました。

# さいごに

まだ課題のあるEChubですが、私が思い描いていたアプリが形となり、デプロイできた瞬間がとても嬉しかったです。また、EChubを開発する中で新しい技術にたくさん触れて、成長することができました。このアプリの開発を行なってとても良かったと感じています。

最後までご覧いただきありがとうございました。