Selenium × Python × HerokuでGoogle ClassroomをスクレイピングするBOTを作った
はじめに
こんにちは。今回はSelenium × Python × Herokuを使ってGoogle Classroomをはじめとしたログインしないとアクセスできないサービスをスクレイピングする方法を書き留めておこうと思います。
バッググラウンド
そもそも何がしたいのかを説明します。
わが校では夕飯を食堂で頼めるという仕組みがありまして、毎日(次の日の)申請フォーム(Google Form
)がクラスルーム(Google Classroom
)送られてきます。当日の午前10:30が締め切りなのですが、意外に忘れる人が多くこれを防止するためにLINE BOT
を作ろうと思いました。
今回の趣旨
今回、大きくやりたいことをまとめると以下のような形になると思います。
-
Heroku
×Python
環境を構築したい。 -
Selenium
をPython
で使いたい。 -
Selenium
をHeroku
上で動かしたい。 -
Selenium
でGoogle Classroom
(など)に入りたい。
1. 環境構築
1.1. PackageのインストールとHeroku Appの生成
Python
× Heroku
の環境構築は多くの方がやられているものと大差ありませんので少し省きつつ構築していきます。また、Python
やpip
はインストールされているものとします。
まずは必要なpackage
をインストールしていきます。
$ pip install flask
$ pip install selenium
次に、Heroku
関係の構築をします。
$ heroku login
出てきたURLにアクセスしてログインしてください。
アプリケーションを生成します。なお、フォルダをその場で生成するのでフォルダ移動を行った後に実行してください。
$ heroku create -a <app-name>
$ cd <app-name>
これでまずは完了です。
1.2. 設定ファイルの準備
次はファイルを作ってアプリとしてdeploy
する準備をしましょう。
先ほど生成した<app-name>
フォルダ内にmain.py
を生成します。
main.py
に仮のコードを書きましょう。
from flask import Flask, request, abort, jsonify
import os
from time import sleep
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
app = Flask(__name__)
@app.route("/")
def hello_world():
return "hello world!"
これでhello_world
のwebhook
ができます。これだけだとHeroku
では動いてくれません。ほかの設定ファイルが必要です。
これでpythonのバージョンとインストールしたpackage
のバージョンを確認します。
$ python --version
$ pip freeze
以下の三つの設定ファイルを<app-name>
フォルダ内に生成します。
runtime.txt
に先ほど確認したpython
のバージョンを書き入れます。
python-3.10.4
requirements.txt
はHeroku
に必要なpackage
を教えます。先ほどpip freeze
で出力されたもののうち、必要なものだけ抜き出します。
Flask==2.1.0
selenium==4.1.3
最後にHeroku
に実行方法を教えます。
web: python main.py
これで初期設定はできました。次はHeroku
にdeploy
しましょう。
1.3. HerokuへのDeploy
deploy
にはgit
を使いますのでインストールを済ましておいてください。
git
でコミットします。
$ git init
Initialized empty Git repository in .git/
一応、Heroku
のリポジトリとつながっているか確認します。
$ git remote -v
heroku https://git.heroku.com/<app-name>.git (fetch)
heroku https://git.heroku.com/<app-name>.git (push)
こうなってれば正解です。なって無ければ以下のコマンドをたたいてください。ちなみに僕はなぜかなっていませんでした。
$ heroku git:remote -a <app-name>
最後にdeploy
の方法ですが、普通のgit
と同じようにcommit
してpush
するだけです。
$ git add .
$ git commit -m "My first commit"
$ git push heroku main
個人的にはGithub Desktop
を使うとやりやすいと思います。(remote
先には十分注意してください。)
ちなみに、webhook
となっているのでhttps://<app-name>.herokuapp.com/
にアクセスするとhello world!
と表示されると思います。
2. Heroku上でSeleniumを動かす
早速Selenium
を動かしていきましょう。
今回はhttps://<app-name>.herokuapp.com/selenium
にPOST
に対して応答するように実装します。
# ...省略
@app.route("/selenium", methods=['POST'])
def seleniumFunc():
options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument("--disable-dev-shm-usage")
driver = webdriver.Chrome(options=options)
driver.get("<your-url>")
# スクレイピング
# 終了
driver.quit()
コードはこれだけです。ですが、触ったことある人ならご存じの通り、Selenium
にはGoogle Chrome
本体とChrome Driver
なるものが必要です。これらは、Heroku
側で準備してもらいます。
まずはHeroku
ダッシュボードの<app-name>
プロジェクトの設定を開いてください。
https://dashboard.heroku.com/apps/<app-name>/settings
Buildpacks
に以下の二つを追加してください。
https://github.com/heroku/heroku-buildpack-chromedriver.git
https://github.com/heroku/heroku-buildpack-google-chrome.git
これで次のdeploy
から設定が適応されます。
これでhttps://<app-name>.herokuapp.com/selenium
に適切なPOST
をすることで内容が実行されます。もちろんFlask
の管轄ですのでGET
などの設定は@app.route("/selenium", methods=['POST'])
をいじることで可能です。
3. SeleniumでGoogleログインする
最後はちょっとしたオマケです。Google
のサービスは優秀で基本的にGoogle Apps Script
でいじることができます。ですが、Classroom
はそうはいきません。生徒の立場である私からでは何もすることができません。そこでスクレイピングをすることでどうにかしようというわけです。
Google
はサイトにアクセスするとCookie
やキャッシュからログイン情報を読み取ります。Heroku
では毎回要求されますのでこれさえ突破してしまえばなんということはありません。
# ...省略
@app.route("/selenium", methods=['POST'])
def seleniumFunc():
# ...省略...
driver.get("https://classroom.google.com/u/1/c/XXXXXXX")
# ログイン情報
login_id = "<your-google-account-mailaddress>"
login_pw = "<your-google-account-password>"
# メールアドレス入力
el_id = driver.switch_to.active_element
el_id.send_keys(login_id)
el_id.send_keys(Keys.ENTER)
sleep(5)
# パスワード入力
el_pw = driver.switch_to.active_element
el_pw.send_keys(login_pw)
el_pw.send_keys(Keys.ENTER)
sleep(10)
# スクレイピング
# 終了
driver.quit()
これで好きなようにスクレイピングできます。簡単ですね。
パスワードべた書きで怖いよってかたはHeroku
標準の環境変数を利用できます。
$ heroku config:set GOOGLE_MAILADDRESS="<your-google-account-mailaddress>" --app <app-name>
$ heroku config:set GOOGLE_PASSWORD="<your-google-account-password>" --app <app-name>
べた書きの代わりに以下のように書けば利用できます。
# ...省略...
login_id = os.environ["GOOGLE_MAILADDRESS"]
login_pw = os.environ["GOOGLE_PASSWORD"]
さいごに
今回は「Selenium × Python × HerokuでGoogle ClassroomをスクレイピングするBOTを作った」ということでHeroku
環境でもスクレイピングをしたい方におすすめのやり方を書きました。
Chrome Driver
やChrome
が用意されていたり、環境変数が簡単に使えちゃうHeroku
最強ですね!なんでもwebhook
にできちゃったり...ほんとにもっと早く出会いたかった代物です。
まぁ一つ難点を挙げるとすれば、Add-on
が無料のものであってもクレジットカード登録が必要という点ですね。私は学生でクレジットカードないのでAdd-on
が利用できませんでした。今回作ったBOTは定時でスクレイピングやデータベース処理などを実行するのですがそれらはすべてGoogle Apps Script
側で実装してfetch
でこのwebhook
をたたいてます。GAS
はトリガー機能が標準だったり、Google Spread Sheet
という最強(笑)のデータベースもあってこっちも扱いやすいです。
ですが、Google
関係のことしかできなかったりと未来はHeroku
のほうが明るいなと思いました。なにせPython
で書けるというがでかい...
さて、ここまでお付き合いありがとうございました。ご自愛くださいませ。
Discussion