Selenium on Colaboratory と時間制限回避手法に関するポエム


今回の神

Google Colaboratory 上でSelenium-webdriverが動くらしい(すごい)

python - WebDriverException: Message: Service /content/chromedriver unexpectedly exited. Status code was: -6 with ChromeDriver Google Colab and Selenium - Stack Overflow

執筆時点(2019/05/03)で1000回も閲覧されていないとかいう知名度の低い情報でしたが、最高ソリューションなので書き残します(加えて、 Colabaratory の時間制限を回避できるかもしれない可能性について提案します ←これはつまりポエムです【要検証】)

Colaboratory上でseleniumを動かす

以下のコードを Colaboratory へコピペするだけでとりあえず動きます。それさえも億劫なひとのために、動作検証用の Colaboratory へのリンクもこちらに用意してあります。
selenium_on_colaboratory_for_share.ipynb - Colaboratory

# install chromium, its driver, and selenium
!apt-get update
!apt install chromium-chromedriver
!cp /usr/lib/chromium-browser/chromedriver /usr/bin
!pip install selenium
# set options to be headless, ..
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
# open it, go to a website, and get results
wd = webdriver.Chrome('chromedriver',options=options)
wd.get("https://www.google.com")
print(wd.page_source)  # results

可能性の話(この記事の本題)

 あとGoogle Coloaboratory上でSeleniumを動かすのは、難しいらしいです(← WebDriverの起動が難しいっぽい)。もし可能だった場合、Google Coloaboratory_fileAでselenumを起動させてGoogle Coloaboratory_fileBを起動し、12時間切れる前にGoogle Coloaboratory_fileBでselenumを起動させてGoogle Coloaboratory_fileCを起動(...以下エンドレスリピート)みたいなウンコプログラムを記述していたのだがorz
Google Colaboratoryを定期実行する方法について考える - Qiita

上記の記事を書いた方は Colaboratory から Selenium が使えるようになったことを知らなかったようですが、発想はかなり面白いと思います。Colaboratory で任意の処理を行なう一方で、制限時間が近づいたらまた別の Colaboratoryに処理を引き継げばいいのでは?どうやったら実現できるか以下のように考えてみました。

  1. Colaboratory_Aで処理を開始する
  2. 制限時間が近づいたら、データをGithubに退避させる
  3. Colaboratory_AからColaboratory_Bを起動する
  4. Githubからデータをcloneし、再度処理を開始する
  5. (1に戻って繰り返す)

このようにすれば、理論上は24時間365日、TPUがフル稼働する無料のPython環境も夢じゃないかも………!?

実装方法の概要

Colaboratoryの起動云々はSeleniumにやらせるとしても、「データをGithubに退避させる」ってどうやるんじゃい、という話があったのですがそこはさすが天下のPython、すでにGitPythonというライブラリが提供されていました。

これを使えば、clone, add, commit, push という最低限のGit操作は簡単にできるようになります。

これであとは、ページのソースとにらめっこしながらSeleniumくんのコードを書くだけや❗❗ 勝ったッ❗❗❗❗ 第三部、完 ❗❗❗❗❗👉👉👉

現在ブチ当たっている壁

けれども大前提として、Colaboratoryを実行するためにはまずGoogleのアカウントにログインする必要がありました。しかしそこはさすがのGoogle、Seleniumからメールアドレスとパスワードを入力してログインできたと思ったのもつかの間、当然の権利であるかのように画像認証のページへと遷移させられてしまいました。失敗です………。

そこでは再度パスワードと、例のグニャグニャしたランダムな文字列を読み取って入力することが求められていました。Seleniumを駆使してその画像をColaboratory上に表示することまではできたものの、テキストを入力するのはcolaboratory単体でやるには至難の業、ほぼ不可能な気がします。

画像認証を突破するために、Colaboratoryの外からどうにかしてテキストを入力する方法を考えねばなりません(そして都合上、なるべく無料で使える方法を検討したい…)。

改善案

画像を取得するところまではできているので、今度はそれをGASこと Google App Script に POST して、それをさらに手元の Slack に投げてもらい、画像を確認してテキストを再度 GAS に投げ返し、それを受け取った GAS が Colaboratory に差し戻す……みたいな

ちょうど、 Colaboratory_A, _B, _C..., を複製していくにあたってGASを使おうと考えていたので都合も良いのですが、まだ完全に理解できておらず、実装が追いついていない状況です(これを読んだGAS職人に任せたいと思います)

また、私の場合は二段階認証を設定していないアカウントで試行したため画像認証が必要になったかもしれないということも考えられます。二段階認証を設定していれば、メールアドレスとパスワードを入力した後、認証コードを入力するだけでよくなるかもしれません。

最終的なシステム全体の構成としては、以下のようになると思います

  • Colaboratory (Selenium + Git + 任意のpythonコードによる処理)
  • Google App Script (ログイン時のやり取りを仲介 + Colaboratoryの複製・削除)
  • Slack (ログイン時の認証情報の入力 + 進捗状況の監視)

処理の流れは以下の通り

  1. Colaboratory_Aで処理を開始する
  2. 制限時間が近づいたら、データを Github に退避させる
  3. Selenium 経由でGoogleアカウントにログイン
  4. その際、GASとslackで人力による入力
  5. Colaboratory_AからColaboratory_Bを起動する
  6. Githubからデータをcloneし、再度処理を開始する
  7. (1に戻って繰り返す)

※二回目以降のログインは、chromeのプロファイル情報が引き継げれば省略できる可能性があるが、今の所不明(できない可能性が高い?)
cf. Python + Selenium + Chrome で自動ログインいくつか - Qiita

おわりに

こんなポエムを書いて検索汚染するのは忍びないという気持ちはありつつも、これを少し改善すれば正しくすべてPythonユーザーにとっての桃源郷が広がっていること間違いなしだと考えたので書き残しました。誰か、実現してくれ~~~~🙏🙏🙏🙏🙏(他力本願)

参考文献

Selenium on Colaboratory の先駆者様たち
Google Colaboratory を定期実行したい人たち
Selenium 関連
GitPython 関連