[無料]Chrome headless + seleniumをherokuで定期実行
headless driverについて
headlessでseleniumを実行すると言えばつい最近まではPhantomJSでしたが、
PhantomJSにはバグが多く存在しているにも関わらず、開発は終了してしまいました。
headlessで実行できるということはGPUを使用せずに実行できるということになります。
通常のwebdriverでは実行するとブラウザが立ち上がって処理を行っていきますが、
headlessではブラウザが立ち上がることなく処理が行われます。
GPUを使用しないということはjenkinsなどで仮想のデスクトップ環境を用意する必要もなくなるわけです。
前述したようにheadlessの代表格だったPhantomJSの多くのバグを残したまま開発が終わってしまいました。
そこで登場した期待の新星がChromeのheadlessモードです。
Chromeのheadlessも登場したばかりの頃は数多くのバグがあって使い物になりませんでしたが、
バージョンが上がるにつれてかなり安定してきたということなので既存のコードをChromeのheadlessモードで実行したところちゃんと動いてくれました。
Googleさんが開発しているシェアNo.1のChromeですから、headlessモードの開発が終わるということもなかなかないのでしょうか。
今あるバグの修正や新機能の実装も期待できるのです。
headlessでいいならherokuで実行できるんじゃね?
heroku とは、PaaS(Platform as a Service)と呼ばれるサービスで、アプリケーションを実行するためのプラットフォームです。
Ruby on Railsチュートリアルなどでも利用されている、軽量のアプリ(現在は500MBまで)なら無料でデプロイできるサービスです。
herokuにはBuildpackというものがあって、これをインストールすることで様々な実行環境を簡単にセットアップできます。
rubyやgoogle chromeやchromedriverのBuildpackもあるので、これならheroku上で動いてくれるんじゃないかと思い格闘してみたところ無事に実装できました。
前置きが長くなりましたが、今回はherokuでChromeDriverのheadlessモードをseleniumで定期実行するということを紹介したいと思います。
さあ実装
seleniumの実装
ぶっちゃけ、seleniumの実装が一番悩んだところで、他はすんなりいけました。
この記事を読む多くの方はここだけ見て離脱するのではないでしょうか。
普通のseleniumのコードと異なるのはdriverの宣言の仕方だけです。
以下のように書いてください。
1 2 3 4 5 6 7 8 9 |
# heroku_chrome_headless.rb にしてみますか。 require 'selenium-webdriver' caps = Selenium::WebDriver::Remote::Capabilities.chrome("chromeOptions" => {binary: "/app/.apt/usr/bin/google-chrome", args: ["--headless"]}) driver = Selenium::WebDriver.for :chrome, desired_capabilities: caps # あとはここにdriverを使って通常のseleniumのコードを実装していけばOK |
このdriverの宣言の仕方はheroku(もしくはUbuntu?)で実行するためのものです。
ローカルでchromedriverのheadlessモードを実行するのであればbinaryを指定する必要はありません。
gitの準備
herokuにはgit pushを利用してデプロイするのでプロジェクトにgitを入れてください。
既にgithubやgitbucketを使っていてSSH keyが生成されている前提です。
1 2 3 |
git init git add -A git commit -m "適当なコメント" |
herokuの準備
heroku への登録を完了させ、コマンドラインからherokuコマンドを使えるようにHeroku CLIを各環境に合うものをインストールします。
Heroku CLI | Heroku Dev Center
herokuコマンドが使えるようになったらコマンドラインからログインします。
1 2 3 4 |
> heroku login Enter your Heroku credentials. Email: <herokuアカウントのメールアドレス入力> Password: <herokuアカウントのパスワード入力> |
これだけでherokuにSSH keyが追加され、git pushが可能になりました。
ruby環境のheroku appを作成
herokuにruby環境のappを作ってみましょう。
とは言っても環境設定は速攻です。
1 |
heroku create --buildpack https://github.com/heroku/heroku-buildpack-ruby.git |
これでrubyのbuildpackがインストールされた環境ができてしまいます。
heroku appにbuildpackを追加
ブラウザでherokuのダッシュボードから先程作成したappの画面にいき上部メニューの”Settings”を開きます。
ページ中腹に”Buildpacks”という項目があるので”Add buildpack”をクリックして以下のbuildpacを追加しましょう。
1 2 3 |
https://github.com/heroku/heroku-buildpack-chromedriver.git https://github.com/heroku/heroku-buildpack-google-chrome.git |
chromedriverとgoogle chrome自体のbuildpackですね。
ここで追加したbuildpackは次回のデプロイ時に同時にインストールされます。
ではデプロイしてみましょう。
herokuにデプロイ
git pushで先程のheroku app環境にデプロイしてみましょう。
1 2 3 4 5 6 7 |
git push heroku master . . . . . remote: Verifying deploy... done. |
となればOKです。
これで環境は整いました。
heroku appの実行
herokuでのコマンドの実行は”heroku run”でコマンドを渡してあげるだけで大丈夫です。
準備したappをコマンドラインから実行してみましょう。
1 |
heroku run "ruby heroku_chrome_headless.rb" |
これで実行されます。
すげえ…感動。。。。。
heroku appの定期実行 “heroku scheduler”
では今度はこのheroku appを定期実行したいと思います。
定期実行するためにはadd-onの”heroku scheduler”をインストールする必要があります。
heroku schedulerは多重に高頻度での実行をしない限りは無料で使うことができるようですが、
「いっぱい使ったらお金払ってね」ということでクレジットカード(デビットカード可らしい)の登録が先に必要になります。
アカウント設定のbillingからカード情報を登録しましょう。
カード情報が登録できたらheroku schedulerをインストールします。
先程のheroku appの上部メニュー”Resources”に遷移し、”Add-ons”で”heroku scheduler”と入力して出てきたHeroku SchedulerをクリックしてProvisionしましょう。
Plan nameが表示されますが、”Standard -Free”しか選択できないと思います。
heroku schedulerのインストールが終わるとheroku appのダッシュボード画面のOverviewにinstalled add-onsとしてheroku schedulerが表示されます。
これをクリックすると別タブでschedulerの画面が開くので”Add new job”で定期実行するコードと頻度が設定できます。
ブラウザ上から設定できるので簡単ですね。コマンドラインから設定する方法もあるようなので好きな方でやってみてください。
それと定期実行がどれくらいの頻度であれば無料で行えるのかは結構変わるみたいなので気になる方は調べてみてください。
seleniumの定期実行くらいなら無料で大丈夫だと思うんですけどね。
Herokuが再度料金体系変更 – flexible free dyno hoursで月1000時間の無料枠(ただし全アプリ横断で) – Qiita
まとめ
というわけでこれでseleniumで日々のルーチン作業なんかを自動化できることが無料で可能になりました。
本当にちゃんと動いてるのかわからないという方はputsなどをコードに仕込めばコマンドラインにちゃんと返ってきますのでやってみてください。
sinatraなどの軽量なフレームワークと組み合わせれば定期的に情報を取ってくるwebアプリも無料でできちゃいそうです。やってみよ。
herokuでchromedoriverをheadlessで起動できるということですが、逆に画面表示させる方法はないでしょうか。
herokuにデプロイした場合、どこに表示させましょうか?VNC的なことですか?
サーバー上でうごくだけなので、表示はできません。
VNC上で環境を作ってheadlessではなく表示させるように実装すればよいですね。
herokuにはリモートデスクトップ的な機能はありません。