はじめに
Google Colaboratory とは、Google社が無料で提供している機械学習の教育や研究用のPythonによる開発環境で、どなたでも無料で利用が可能です。私は2021年11月頃から仮想通過に興味を持ち始めたのですが、最近は仮想通貨の自動トレードプログラム(ボットBot)を作成しています。このボットを自動で実行する環境として、ローカル環境ではなく何かクラウド上で無限ループ実行できれないかと思い調べていた時に見つけたのがこのGoogle Colaboratoryでした。しかし、このColaboratoryには以下のような欠点があります(課金している方は別ですが)。
- 90分間ローカルPCを動かしていなければセッションリセット
- 12時間後に強制的にランタイムリセット
私のようにボットをColaboratory上で無限に実行し続けたければ、この2点の問題に対処する必要があります(もちろん無課金で)。ということで、私が色々試してみて実際に無限ループできた(実際は約4日間だけですが…)ので、その際にハマったポイントについて私の備忘録も兼ねて書いていこうと思います。私と同じような悩みを抱えている皆さんの参考程度になれば幸いです。
前提
これをやるにあたって、私はずっと以下のサイトを参考にしていますので、まず最初に以下のサイトの内容をご覧ください。以下のサイトに記載の内容で重複する内容に関しては、ここでは割愛させていただきます。
開発環境
- Windows 10 x64 Enterprise LTSC
- Docker Desktop 3.3.1
注意すべきポイントと実行結果
Googleユーザープロファイルの作成
このユーザープロファイルは、Colab上でSeleniumを使いchromiumをヘッドレスで立ち上げてプログラムを実行する際に、毎回パスワードの入力を省略するために必要となります。私は最初ここでハマりました。というのも、私はこのときWindows 10 Homeを使っていたので、Docker Desktopをインストールして正常に使うことができませんでした。なので、当時はVMWare Workstationという仮想化マシン上にUbuntu 18.04環境をisoファイルから構築し、UI操作によりユーザープロファイルの作成を試みていました。で、ユーザープロファイル自体は普通に作成(Seleniumによる新規作成、ログイン後に自動生成されるユーザープロファイル、両方ともOK)できたのですが、Colab上で ファイルA から、github経由で自分のユーザープロファイルを読み込んでみたのですが、認証がどうもうまくいきませんでした(未だに理由は不明)。
しばらくして、私が新しいPC(Windows 10 Enterprise)に買い替えたので、今度はDocker Desktopをインストールして(ちゃんと動いた!)、Docker上にUbuntu 18.04環境を構築して、以下のサイトを参考にUbuntu 18.04をUI上から操作して、ユーザープロファイルを作成しました。
で、結果このとき作成したユーザープロファイルを使ったら、見事Colab上でパスワード認証せずにSeleniumのchromiumからプログラムを呼び出し実行することに成功しました!結局理由はよくわかりませんでしたが、Googleユーザープロファイルの作成は、仮想マシン上ではなく、Docker上で作成すればうまくいくようです。Windows Homeユーザーの方はEnterprise版にアップデートしましょう!
ファイルAの実行時間
デフォルトでファイルAの実行時間は、
11時間未満なら再読み込み、11時間以上ならファイルBを開く
になっていると思います。私も初めはこの実行時間の設定で試してみたのですが、色々試しているうちにどうやら実行時間が6時間以上経つと、なぜかランタイムが切れるということが分かったため、実行時間に関する条件を
6時間未満なら再読み込み、6時間以上ならファイルBを開く
に変更して実行してみたところ、見事約4日間の連続ループに成功しました!
プログラムコードを微修正
1つ目は、クラスSeleniumColaboratoryの関数click_runall()内を以下のように変更します。
// 変更前 // select_dropdown = WebDriverWait(self.driver, 20).until(EC.element_to_be_clickable((By.ID,":1s"))) // 変更後 select_dropdown = WebDriverWait(self.driver, 20).until(EC.element_to_be_clickable((By.ID,":1v")))
注意:このID(:1sとか:1v)は頻繁に変わっているので、プログラムの実行前に一回確認してみてください。私が無限ループに成功したときは”:1v”でした。
2つ目は、関数click_change_runtime()です。以下のように変更しましょう。
def click_change_runtime(self): """ ランタイムのタイプを変更する関数 """ # ランタイムクリック select_dropdown = WebDriverWait(self.driver, 20).until(EC.element_to_be_clickable((By.ID,"runtime-menu-button"))) select_dropdown.click() # ランタイムのタイプ変更クリック # select_dropdown = WebDriverWait(self.driver, 20).until(EC.element_to_be_clickable((By.ID,":23"))) select_dropdown = WebDriverWait(self.driver, 20).until(EC.element_to_be_clickable((By.ID,":26"))) # ←のIDもちょくちょく変わるので実行前に1回確認しておいてください select_dropdown.click() # ドロップダウンクリック # select_dropdown = WebDriverWait(self.driver, 20).until(EC.element_to_be_clickable((By.ID,"input-4"))) # このIDは現在存在していないのでコメントアウト # select_dropdown.click() # 待たずにクリックしてしまうことがあるので time.sleep(1) # XPATH避けたい # ランタイム選択 # select_dropdown = WebDriverWait(self.driver, 20).until(EC.element_to_be_clickable((By.XPATH,"//*[@id='accelerator']/paper-item[" + self.mode + "]"))) select_dropdown = WebDriverWait(self.driver, 20).until(EC.element_to_be_clickable((By.XPATH,"//*[@id='accelerator']/option[" + self.mode + "]"))) # 指定するXpathが変わっています。 select_dropdown.click() # 保存ボタンクリック select_dropdown = WebDriverWait(self.driver, 20).until(EC.element_to_be_clickable((By.ID,"ok"))) select_dropdown.click()
ちなみに、今回はファイルAもBもランタイムを”None”(CPU)に変更して実行しました。
実行結果
elapsed_time.txtへの出力結果を一応載せておきます。
------------------ 2021-05-17 ------------------ File A : 0.0703111 Hour (07:18:37) File A : 1.08045 Hour (08:19:14) File A : 2.09053 Hour (09:19:50) File A : 3.10058 Hour (10:20:26) File A : 4.11065 Hour (11:21:03) File A : 5.12095 Hour (12:21:40) File A : 6.13128 Hour (13:22:17) ------------------ 2021-05-17 ------------------ File B : 0.0341333 Hour (13:23:22) File B : 0.544167 Hour (13:53:58) File B : 1.05412 Hour (14:24:34) File B : 1.56407 Hour (14:55:10) ------------------ 2021-05-17 ------------------ File A : 0.0267944 Hour (14:56:10) File A : 1.03691 Hour (15:56:47) File A : 2.0471 Hour (16:57:23) File A : 3.05722 Hour (17:58:00) File A : 4.06744 Hour (18:58:37) File A : 5.07792 Hour (19:59:14) File A : 6.08846 Hour (20:59:52) ------------------ 2021-05-17 ------------------ File B : 0.0557639 Hour (21:00:58) File B : 0.565678 Hour (21:31:34) File B : 1.07569 Hour (22:02:10) File B : 1.58569 Hour (22:32:46) ------------------ 2021-05-17 ------------------ File A : 0.0463861 Hour (22:33:47) File A : 1.05657 Hour (23:34:23) File A : 2.06666 Hour (00:35:00) File A : 3.0767 Hour (01:35:36) File A : 4.08686 Hour (02:36:12) File A : 5.09742 Hour (03:36:50) File A : 6.10796 Hour (04:37:28) ------------------ 2021-05-18 ------------------ File B : 0.199147 Hour (04:38:36) File B : 0.709242 Hour (05:09:12) File B : 1.21932 Hour (05:39:48) File B : 1.72942 Hour (06:10:25) ------------------ 2021-05-18 ------------------ File A : 0.0273694 Hour (06:11:26) File A : 1.03764 Hour (07:12:03) File A : 2.04787 Hour (08:12:40) File A : 3.05801 Hour (09:13:16) File A : 4.06828 Hour (10:13:53) File A : 5.07865 Hour (11:14:30) File A : 6.08912 Hour (12:15:08) ------------------ 2021-05-18 ------------------ File B : 0.0511444 Hour (12:16:14) File B : 0.561133 Hour (12:46:50) File B : 1.0713 Hour (13:17:27) File B : 1.58129 Hour (13:48:03) ------------------ 2021-05-18 ------------------ File A : 0.0418278 Hour (13:49:02) File A : 1.05191 Hour (14:49:39) File A : 2.06199 Hour (15:50:15) File A : 3.07198 Hour (16:50:51) File A : 4.08215 Hour (17:51:27) File A : 5.09239 Hour (18:52:04) File A : 6.10274 Hour (19:52:42) ------------------ 2021-05-18 ------------------ File B : 0.325481 Hour (19:53:47) File B : 0.835817 Hour (20:24:25) File B : 1.34583 Hour (20:55:01) File B : 1.8558 Hour (21:25:37) ------------------ 2021-05-18 ------------------ File A : 0.0337167 Hour (21:26:35) File A : 1.04421 Hour (22:27:13) File A : 2.05435 Hour (23:27:50) File A : 3.06445 Hour (00:28:26) File A : 4.07469 Hour (01:29:03) File A : 5.08501 Hour (02:29:40) File A : 6.09596 Hour (03:30:20) ------------------ 2021-05-19 ------------------ File B : 0.260231 Hour (03:31:24) File B : 0.770369 Hour (04:02:00) File B : 1.28043 Hour (04:32:37) File B : 1.79035 Hour (05:03:12) ------------------ 2021-05-19 ------------------ File A : 0.0485722 Hour (05:04:14) File A : 1.05878 Hour (06:04:50) File A : 2.06901 Hour (07:05:27) File A : 3.07928 Hour (08:06:04) File A : 4.08961 Hour (09:06:41) File A : 5.10011 Hour (10:07:19) File A : 6.11064 Hour (11:07:57) ------------------ 2021-05-19 ------------------ File B : 0.0766639 Hour (11:08:56) File B : 0.586583 Hour (11:39:32) File B : 1.09646 Hour (12:10:07) File B : 1.60633 Hour (12:40:43) ------------------ 2021-05-19 ------------------ File A : 0.160431 Hour (12:41:47) File A : 1.17066 Hour (13:42:24) File A : 2.18089 Hour (14:43:01) File A : 3.19151 Hour (15:43:39) File A : 4.20191 Hour (16:44:16) File A : 5.21319 Hour (17:44:57) File A : 6.22371 Hour (18:45:35) ------------------ 2021-05-19 ------------------ File B : 0.033425 Hour (18:46:42) File B : 0.543667 Hour (19:17:19) File B : 1.05394 Hour (19:47:56) File B : 1.56392 Hour (20:18:32) ------------------ 2021-05-19 ------------------ File A : 0.0291306 Hour (20:19:33) File A : 1.03928 Hour (21:20:10) File A : 2.04946 Hour (22:20:46) File A : 3.05999 Hour (23:21:24) File A : 4.07023 Hour (00:22:01) File A : 5.08064 Hour (01:22:39) File A : 6.09105 Hour (02:23:16) ------------------ 2021-05-20 ------------------ File B : 0.0293111 Hour (02:24:30) File B : 0.539989 Hour (02:55:08) File B : 1.05007 Hour (03:25:44) File B : 1.56016 Hour (03:56:21) ------------------ 2021-05-20 ------------------ File A : 0.0255389 Hour (03:57:23) File A : 1.03587 Hour (04:58:00) File A : 2.04602 Hour (05:58:36) File A : 3.05609 Hour (06:59:13) File A : 4.06615 Hour (07:59:49) File A : 5.07628 Hour (09:00:25) File A : 6.08664 Hour (10:01:03) ------------------ 2021-05-20 ------------------ File B : 0.0297306 Hour (10:02:03) File B : 0.539544 Hour (10:32:38) File B : 1.0494 Hour (11:03:13) File B : 1.55919 Hour (11:33:49) ------------------ 2021-05-20 ------------------ File A : 0.0524528 Hour (11:34:51) File A : 1.06266 Hour (12:35:28) File A : 2.07291 Hour (13:36:05) File A : 3.08301 Hour (14:36:41) File A : 4.09325 Hour (15:37:18) File A : 5.10371 Hour (16:37:55) File A : 6.11423 Hour (17:38:33) ------------------ 2021-05-20 ------------------ File B : 0.035625 Hour (17:39:38) File B : 0.545703 Hour (18:10:15) File B : 1.0557 Hour (18:40:51) File B : 1.56581 Hour (19:11:27) ------------------ 2021-05-20 ------------------ File A : 0.0585278 Hour (19:12:34) File A : 1.06879 Hour (20:13:11) File A : 2.07903 Hour (21:13:48) File A : 3.08918 Hour (22:14:24) File A : 4.09957 Hour (23:15:02) File A : 5.11015 Hour (00:15:40) File A : 6.12071 Hour (01:16:18) ------------------ 2021-05-21 ------------------ File B : 0.0460639 Hour (01:17:33) File B : 0.556875 Hour (01:48:12) File B : 1.06763 Hour (02:18:51) File B : 1.57803 Hour (02:49:28) ------------------ 2021-05-21 ------------------ File A : 0.0381806 Hour (02:50:35) File A : 1.04855 Hour (03:51:12) File A : 2.05901 Hour (04:51:50) File A : 3.06936 Hour (05:52:27) File A : 4.07973 Hour (06:53:05) File A : 5.09023 Hour (07:53:42) File A : 6.09783 Hour (08:54:10)
まとめ
Google Colabは頻繁にHTMLのIDがアップデートされているようなので、毎回プログラムの実行前にXpathを確認して、指定しているIDが正しいかどうかをチェックしておいた方がよいでしょう。今後も何かアップデートがあれば、こちらの記事を更新していく予定です。