Python
Selenium
python3
GoogleColaboratory

Google Colaboratoryを定期実行する方法について考える

Google Colabratoryのセッション切れ対策&定期実行について

 Google Colabratoryは、現状ノートブックのセッションが切れてから90分後に、あるいはインスタンス起動してから12時間後にリセットされる仕様になっている。Google Colabratoryにはタイマー実行で定刻に実行する機能が現時点ではないので、なんとか無理やりセッションが切れないようにしたり、あるいは定期的にタイマー実行する方法を考えるというのが本イシューの趣旨。

4.png
 某スケベサイエンティストがツイートしてましたが、激しく同意。現在Google ColabratoryにはAPIが用意されておらず、Google SpreadsheetのGoogle app scriptに用意されているような定期実行(タイマー処理)の機能がないので、Google Colabratoryにも同様な機能があればと夢想する次第です。

セッション切れ対策

 この記事のようにchromeのアドオン「Auto Refresh」を利用するのもひとつの案ですね。初回のGoogle Colabratoryの起動とセル実行は手動なのはまあ仕方がないにしても、少なくとも90分のノートブックのセッション切れは回避可能かと。

参考:Auto Refresh
https://chrome.google.com/webstore/detail/auto-refresh/ifooldnmmcmlbdennkpdnlnbgbmfalko
※Chromeのアドオン

 あるいは以下のようにscheduleを使ってセッションを切らさないよう「常時稼働させる」方向で90分のセッション切れを回避するというのも手かと。ただしこれを稼働させても90分のセッション切れは回避可能できるが、12時間後のインスタンスのリセットは回避できない。

schedule.py
!pip install schedule

import time
import schedule
from datetime import datetime

def job():
    #現在日時の表示
    dt = datetime.now().strftime("%Y/%m/%d %H:%M:%S")
    print(dt)
    print('ほげ')


##2分毎にjobを実行
schedule.every(2).minutes.do(job)

##毎時間ごとにjobを実行
#schedule.every().hour.do(job)

##PM15:10にjobを実行
#schedule.every().day.at("15:10").do(job)

##月曜日にjobを実行
#schedule.every().monday.do(job)

##水曜日の13:15にjobを実行
#schedule.every().wednesday.at("13:15").do(job)

while True:
    schedule.run_pending()
    time.sleep(1)

 ちなみにGoogle Colaboratoryで現在日時を取得すると、日本時間が返ってこないです。実際のPythonの実行環境は海外のどこかなのでしょう。自分の実行環境ではヨーロッパのアイスランド付近の時間が返ってきました。
(注:自分がGoogle Colaboratoryを使う理由は実は逆にココだったりする。スクレイピング等を実行する場合、発信元IPアドレスが日本でなく世界のどこかのサーバのほうが好都合...以下自重

定期実行について

 いろいろ方法を考えたのですが、とりあえずローカルPC上にてSelenumでGoogle Driveにログインして、Google Colabratoryのファイルを開いて一番上のセルの実行ボタンをクリックするpythonプログラムを定期実行する(WindowsPCの場合はタスクスケジューラを、MacやLinuxの場合はCrontabを設定)という方法しか思い浮かばなかったです。

exec_gcolab.py
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time

driver = webdriver.Chrome()
url = 'https://colab.research.google.com/drive/1234567890abcdefghijklmn'

login_id = 'hogehoge@gmail.com'
pas = 'fugafuga_pwd'

# ページを開く
driver.get(url)

time.sleep(5)
# ログイン画面:userid
driver.find_element_by_xpath("//*[@id='identifierId']").send_keys(login_id)
driver.find_element_by_class_name('CwaK9').click()
time.sleep(2)

# ログイン画面:pwd
driver.find_element_by_xpath("//*[@id='password']/div[1]/div/div[1]/input").send_keys(pas)
driver.find_element_by_xpath("//*[@id='passwordNext']").click()
time.sleep(10)

# Google Colab
print(driver.current_url) 
driver.find_element_by_class_name('cell-execution').click() #セルの実行

 Google Coloaboratoryのセルの実行ボタンはHTMLソースを見ると、divタグのclass名「cell-execution」で記述されている。
2.png
 要はGoogle Coloaboratory上でショートカットキー「Ctrl + Enter」を押すか、あるいは上記画像のように一番上のセルのボタンをクリックするかが実現できれば自動実行が可能ということだが、そもそもローカルPCのPython環境でSeleniumを稼働させているので、だったらGoogle Colaboratoryで稼働させるpythonプログラムを、最初からローカルPCのPython環境で稼働させろやというツッコミもなきにしもあらずであり、イマイチスマートなやり方ではないのは正直否めないです。

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

※参考:「Colaboratory上でSeleniumが使えないか試した(そしてダメだった)」↓
https://qiita.com/FrozenVoice/items/5348a74feeb5e8b8b8ad

結論

 とりあえずGoogle ColoaboratoryのAPI機能リリース待ち、あるいはGoogle Coloaboratoryの定期実行機能リリース待ちということで。