Jリーグのデータを検索できるサービスを作った


概要

記事概要

今回作ったサービスの紹介をしつつ開発の流れやつまずきポイントを紹介します。
似たものを作る人の参考になれば・・・

アプリ概要

  • サッカーJリーグのデータを検索できるサービスをです。
  • こちらから検索サイトに飛べます
  • JリーグのデータをスクレイピングするWebAPIと検索するフロント画面で構成されます。
  • 現在は2017〜2019の連勝記録を調べられます。
  • フロントの検索画面

アプリ作成理由

  • 川崎フロンターレというサッカーJリーグのチームのサポーターなのだが、2020年に今までの連勝記録を更新(10連勝!)をしたことをきっかけに過去のデータを調べたくなった。
  • WebAPIをより理解するために自分で作りたくなった。

全体の構成

フロントバックのソースコードはGitHubにあげています。

サーバー構成図

ER図

使用技術

  • Python (ライブラリにFlask)
  • Docker
  • MySQL
  • Javascript(フロント)

作成の流れ&つまづきポイント

流れ

  1. Dockerで環境構築
  2. JリーグのデータサイトをスクレイピングしてDB作成
  3. Flask APIを使ってデータをWebAPIにする
  4. AWSにデプロイ

流れの詳細

参考にしたサイトなどを紹介しつつ開発の流れを説明します。

1. Dockerで環境構築

ベースはこちら(Docker内でMySQLにPythonで接続する)を参考にしました。

version: "3"

services:
  mysql_db_j:
    container_name: "mysql_db_j"
    image: mysql:5.7
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
    environment: # Set up mysql database name and password
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: employees
      MYSQL_USER: user
      MYSQL_PASSWORD: password
    networks:
      - app-tier

  python3_j:
    restart: always
    build: .
    ports:
      - '3000:3000'
      - '5000:5000'
    container_name: "python3_j"
    working_dir: "/root/"
    tty: true
    stdin_open: true
    depends_on:
      - mysql_db_j
    networks:
      - app-tier
    volumes:
      - .:/root/app/
    # command: python3 app/app.py
    command: >
      bash -c "python3 app/create_teamid.py
      && python3 app/create_result.py
      && python3 app/app.py
      "

networks:
  app-tier:
    driver: bridge

MySQLとPythonのコンテナを立ち上げて接続させています。
また。command:で起動時にDB作成とFlaskが起動するようにしています。

2. JリーグのデータサイトをスクレイピングしてDB作成

スクレイピングはrequestsbeautifulsoupを使っています。
PythonからMySQlへの接続はmysql-connector-pythonを使いました。
ここらへんを参考に
Python + mysql-connector-python の使い方まとめ
Python3でMySQL Connectorのインストール・接続方法【快適に使う方法を紹介】
公式ドキュメント

3. Flask APIを使ってデータをWebAPIにする

FlaskAPIを使ってDBに保存したデータをJSONにして送っています。
参考
Flaskの簡単な使い方

また、flask_corsを使わないと

Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

というようなエラーが出ます。CROS対策で必要です。

4. AWSにデプロイ

以下を参考にEC2にDockerをインストールしてDockerを起動させてます。ホントはECSとか使いたかった・・・
参考
AWS EC2インスタンスにdockerとdocker-composeをインストールして簡単なWEBサービスを立ち上げる方法
EC2でDockerコンテナを起動し、Flaskを動かす(Flaskで簡単なWebサービスを作ってみる[第5回])

つまづきポイント

設計どうすればいいの・・・

いざWebAPIを開発しようとして、「初めの一歩」の参考になる情報があまり見つからなかったですね。Restfulの原則の解説などはいろいろありますが、じゃあ実際どう作るのがスタンダードなの?ってなってしまいますね。
とりあえず今までWebAPIを利用した経験で設計してみました。

DBが保存されてない!?

mysql-connector-pythonというライブラリでMySQLに接続していたのですが、Pythonから操作した時に、DBの追加処理をしても保存されないという問題が発生。ずっと詰まっていたのですが、公式ドキュメントに「デフォルトではConnector / Pythonは自動コミットしないため、トランザクションストレージエンジンを使用するテーブルのデータを変更するすべてのトランザクションの後にこのメソッドを呼び出すことが重要です。」と書いてあった。ドキュメントはちゃんと読まないとね!

AWSむずし

フロント側をGithubPagesで公開すると以下のようなエラーが

index.js:30 Mixed Content: The page at 'https://yuta97.github.io/j-search-front/' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://18.178.166.9:5000/continuous-records/match/win/?yearFrom=2017&yearTo=2019&continuou_recordFrom=2&continuou_recordTo=15'. This request has been blocked; the content must be served over HTTPS.

要はhttpsのサイトの中でhttpのAPIサーバを呼び出していることが問題のようです。
このような混合コンテンツは非推奨のようですね。
解決策としてEC2のAPIサーバーをSSL化使用としましたがうまく行かない・・・
苦肉の策としてS3でホスティングし、フロントをhttp通信にすることで対応。

感想

感想をだらだらと書きます。

  • アジャイル開発みたいに小さく作って改善してくのが自分の精神衛生上大事だな。
  • メディアの人は記録更新とかどうやって調べてるんだろう?何かデータベースがあるのかな?
  • AWSは使いつつ慣れるしかないな。まだまだ理解が足りん。
  • セキュリティももっと知りたいな。どんな攻撃があるか知らないと、対策もわからん。

今後の展望

今後やりたいことをだらだらと列挙していきます。

  • ソート機能
  • その他のデータ(連敗、負けなしとか)も検索
  • セキュリティーの強化(APIkey入れるとか)
  • APIテスト
  • APIのドキュメント作成(swaggerでできる?)
  • AWS(APIGateWay,ECS,RDS)の他のサービス利用
  • SSL化
  • 最新のデータを自動収集
  • UIの改善(Vue.jsとか使いたい)
  • CICD
  • クイズ作成