はじめに
AWS EC2を使用してSeleniumを活用したスクリプトをCronを使って定期実行する手順を紹介します。
当初は、AWS Lambda上で定期実行することを考えていましたが、Python3.7でseleniumを起動している記事が多く、うまくスクレイピングが出来ず悩んでいました。
23年10月ごろにPython3.7のサポートが終了しているため、うまくいかないと考えられます。
EC2で仮想サーバーを立て、そのサーバーにChromedriver等をインストールして、Cronで定期実行する方法だとうまく実行できたため、今回記事にしました。
簡単な流れ
- EC2インスタンスのセットアップ - AWSで無料枠のLinux EC2インスタンスを立ち上げます
- 必要なツールのインストール - Python、Selenium、およびWebDriverをEC2インスタンスにインストールします
- Pythonスクリプトの作成 - 定期実行したいPythonスクリプトを作成します
- Cronの設定 - スクリプトを定期的に実行するためにCronを設定します
現在の環境
- Windows 11
- Python 3.11.5
- Anaconda 3
- VSCode
ステップ1: EC2インスタンスのセットアップ
EC2からEC2インスタンスを作成・起動し、WindowsのコマンドプロンプトからSSHで接続します。
EC2インスタンスの作成からPython3のインストールまでは、以下の記事を参考にさせていただきました。
SSHでのログインはSSHのキーペアを保存しているディレクトリに移動してから、実行します。
例えばキーペアのPATHがC:\Users\Username\Documents\key.pem
だと、以下のようにするとログインでき ます。Prompt# cd C:\Users\Username\Documents # ssh -i key.pem ec2-user@[パブリックIPv4アドレス]
ステップ2: 必要なツールのインストール
Python3のインストール後、実行したいスクリプトに必要なツール等をインストールしていきます。
Chromedriverのインストールからselenium等のツールのインストールまでは、先ほどと同様以下の記事を参考にさせていただきました。
ここでは、ChromeとChromedriverのバージョンを一致、もしくはChromedriverのバージョンがChromeよりも小さい数値になるようにしてください。私は、それぞれのバージョンを
Chrome:121.0.6261.57
に揃えました。
ステップ3: Pythonスクリプトの作成
定期時刻させたいPythonスクリプト test.py
を作成し、vimでスクリプトを貼り付けます。
# vi test.py
これでスクレイピングができるか確認してみます。
# python test.py
ここで、Chromedriverの設定不良でスクレイピングがうまくいかない場合、スクリプト内のChromedriverのPATHの指定が出来ていない可能性があります。その場合、一度ChromedriverのPATHを調べて、そのPATHをスクリプトに貼り付けて指定してください。
# find -name "Chromedriver"
./.pyenv/versions/3.11.5/lib/python3.11/site-packages/chromedriver_binary/chromedriver
今回、ChromedriverのPATHが./.pyenv/versions/3.11.5/lib/python3.11/site-packages/chromedriver_binary/chromedriver
と分かったので、test.pyのchromedriverのPATH指定をこれに変更していきます。
以下はサンプルコードです。
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
options = webdriver.ChromeOptions()
options.add_argument("--headless")
service = webdriver.chrome.service.Service(executable_path='./.pyenv/versions/3.11.5/lib/python3.11/site-packages/chromedriver_binary/chromedriver')
driver = webdriver.Chrome(service=service, options=options)
driver.get('https://www.google.co.jp')
element_text=driver.find_element(By.CLASS_NAME,"MV3Tnb").text
print(element_text)
driver.quit()
Googleについて
と出力されれば正常に動いています。
ステップ4: Cronの設定
次は、このスクリプトを定期実行するための設定を行います。定期実行にはCron
を用います。指定した時間に、指定したプログラムを動かしてくれる仕組みです。
こちらの記事を参考にしました。
1. Cronのインストール
Cronをインストールしていきます。
# sudo yum install cronie -y
Complete!
# sudo systemctl enable crond.service
# sudo systemctl start crond.service
# sudo systemctl status crond | grep Active
Active: active (running) since ~
2. 定期実行の設定
インストールが終了したら、次は定期実行の設定をしていきます。
$ Crontab -e
これを実行すると、vimエディタが開きます。空白のエディタが開くと思いますが、そこに以下の文章を作成していきます。とりあえず、以下をコピペしてください。
SHELL=
PATH=
HOME=
# For details see man 4 crontabs
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
# run-parts
#01 * * * * root run-parts /etc/cron.hourly
#05 2 * * * root run-parts /etc/cron.daily
#20 2 * * 0 root run-parts /etc/cron.weekly
#40 2 1 * * root run-parts /etc/cron.mointhly
コピペ後、各項目を入力していきます。
SHELL
PATH
HOME
には、自身の環境に応じて入力してください。
項目は$ printenv
でPATH等を取得します。
# printenv
SHELL=/bin/bash
PYENV_SHELL=...
HISTCONTROL=...
SYSTEMD_COLORS=...
HISTSIZE=...
HOSTNAME=...
PWD=...
LOGNAME=...
XDG_SESSION_TYPE=...
MOTD_SHOWN=...
HOME=/home/ec2-user
...
...
...
3. PATHの確認
実行したいスクリプトのPATHと、Python3の実行環境を確認します。それぞれのPATHをメモしてください。
# find `pwd` -name "test.py"
/home/ec2-user/test.py
# which python3
~/.pyenv/shims/python3
4. エラーログファイルの作成
エラーログを確認するためのファイルを作成します。
$ vi cron-error.log
空白のまま保存して終了します。このファイルのPATHもメモしてください。
5. 定期実行の時間の設定
$ Crontab -e
でもう一度Vimエディタを開きます。
SHELL=/bin/bash
PATH=/home/ec2-user/.pyenv/shims:/home/ec2-user/.pyenv/bin:/home/ec2-user/.local/bin:/home/ec2-user/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin
HOME=/home/ec2-user
# For details see man 4 crontabs
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
# run-parts
#01 * * * * root run-parts /etc/cron.hourly
#05 2 * * * root run-parts /etc/cron.daily
#20 2 * * 0 root run-parts /etc/cron.weekly
#40 2 1 * * root run-parts /etc/cron.mointhly
37 14 * * * ~/.pyenv/shims/python3 /home/ec2-user/test.py > /home/ec2-user/cron-error.log 2>&1
# run-parts
の項目の下に、実行したいスクリプトと、時間を入力していきます。
時間の項目は、
分
時間
日
月
曜日
の順番になっています。指定しない項目には*
を入力してください。
例えば上記のスクリプトでは、37 14 * * *
なので、14時37分になると右の文章が定期実行されます。
10分毎に実行したい場合は、*/10 * * * *
のように入力します。
詳しい設定はこちらを確認してみてください。
時間の入力後は、[Python3のPATH] [test.pyのPATH] > [cron-error.logのPATH] 2>&1
と入力します。
ここでは「Python3を使ってtest.py
を実行し、その結果とエラーメッセージをcron-error.log
に出力する」ことを行っています。
6. ログへの書き込み権限の設定
定期実行の結果を cron-error.log
に書き込む操作を行っているため、このファイルに書き込み可能となるように権限を付与します。
# ls -la
-r--r--r--. 1 ec2-user ec2-user 0 cron-error.log
-rw-------. 1 ec2-user ec2-user 7957 test.py
書き込みが必要なため、chmod
で644
を設定します。
$ chmod 644 cron-error.log
また、test.pyにも実行権限が必要なため、700
を設定します。
$ chmod 700 test.py
権限については以下を参照してください。
https://web.tku.ac.jp/~densan/local/permission/permission.htm
7. ログの確認
実際に実行されるかを確認します。
$ sudo tail -f /var/log/cron
Jan 01 00:00:00 ip---- CROND[10831]: (ec2-user) CMD (~/.pyenv/shims/python3 /home/ec2-user/test2.py > /home/ec2-user/cron-error.log 2>&1)
Jan 01 00:00:04 ip---- CROND[10828]: (ec2-user) CMDEND (~/.pyenv/shims/python3 /home/ec2-user/test2.py > /home/ec2-user/cron-error.log 2>&1)
-f
をつけることで、リアルタイムに実行状況を確認できます。
結果やエラーログの確認は以下のコマンドを実行します。
$ cat cron-error.log
まとめ
EC2上でPythonとSeleniumのスクリプトをCronで定期実行する方法を紹介しました。
これにさらにAWSの EventBridge
を用いることで、必要最小限の時間だけインスタンスを起動し、スクリプトの定期実行が行えるようになります。
参考記事