JsoupとSeleniumを使ったKotlin製のスクレイピングタスクをGithubActionsで定期実行する
はじめに
先日、読書記録をスクレイピングするスクリプトをKotlinで作りました。そのスクリプトはGithubActionsで毎週水曜日の深夜3時に定期実行するようにしています。
また、スクレイピング用のライブラリにはJsoupとSeleinumを使いました。
読書メーターの読書記録をJSON形式で出力するスクリプトを作りました!
実装とGithubActionsの設定を簡単にまとめておきます。
ライブラリを準備
何はともあれ必要なライブラリをbuild.gradle.kts
に追加。
implementation("org.jsoup:jsoup:1.14.1")
implementation("org.seleniumhq.selenium:selenium-java:3.141.59")
implementation("org.seleniumhq.selenium:selenium-support:3.141.59")
WebDriverとしてChromeDriverを以下のサイトからダウンロードします。他のWebDriverでも問題ないかと思います。
ダウンロードしたchromedriver
をプロジェクトに./chromedriver
として配置しておきます。
JsoupとSeleniumでスクレイピング
以下が簡単なサンプルコードです。JsoupやSeleniumの詳しい使い方は適宜調べてください。
fun main() {
// seleniumをセットアップ
System.setProperty("webdriver.chrome.driver", "./chromedriver")
val options = ChromeOptions().apply { addArguments("--headless") }
val driver = ChromeDriver(options)
// seleniumからWebページにアクセス
driver.get("https://sample.com")
// ページのソースを取得
val pageSource = driver.pageSouce
// JsoupのDocument型に変換
val document = Jsoup.parse(pageSource)
// JsoupのDocumentから必要な要素にアクセスし、スクレイピングタスクを走らせる
println(document.selectFirst("target_element"))
}
次に、上記をGithub Actionsを使って定期実行させるようにします。
いざGithubActions
以下がGithubActionsの設定ファイルです。
name: scraping
on:
schedule:
- cron: '0 18 * * 2'
jobs:
run:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up chromedriver
run: |
MAJOR_CHROME_VERSION=$(google-chrome --version | sed -r 's/^[^0-9]*([0-9]*).*$/\1/g')
LATEST_VERSION=$(curl -s https://chromedriver.storage.googleapis.com/LATEST_RELEASE_$MAJOR_CHROME_VERSION)
curl https://chromedriver.storage.googleapis.com/$LATEST_VERSION/chromedriver_linux64.zip --output ./chromedriver_linux64.zip
unzip chromedriver_linux64.zip
- name: Set up JDK 11
uses: actions/setup-java@v2
with:
java-version: '11'
distribution: 'adopt'
- name: Build with Gradle
run: ./gradlew build
- name: Run with Gradlew
run: ./gradlew run
GithubActionsにおけるGradleの設定は公式のドキュメントがあったのでそちらを参考にしました。
また、以下の部分でChromeDriverの準備をしています。
- name: Set up chromedriver
run: |
MAJOR_CHROME_VERSION=$(google-chrome --version | sed -r 's/^[^0-9]*([0-9]*).*$/\1/g')
LATEST_VERSION=$(curl -s https://chromedriver.storage.googleapis.com/LATEST_RELEASE_$MAJOR_CHROME_VERSION)
curl https://chromedriver.storage.googleapis.com/$LATEST_VERSION/chromedriver_linux64.zip --output ./chromedriver_linux64.zip
unzip chromedriver_linux64.zip
この箇所を少し補足しておきますと、google-chrome --version
で出力されるバージョンのドライバーが必ずしもダウンロードできるとは限りません。そのため、sed -r 's/^[^0-9]*([0-9]*).*$/\1/g'
でメジャーバージョン部分のみを抽出し、そのメジャーバージョンの中でダウンロード可能なバージョンをAPIから取得、最後にそのバージョンを使ってドライバーのzipをダウンロードするといった流れになっています。
定期実行の部分については、以下です。以下の例では毎週水曜日の日本時間AM3:00にタスクを定期実行します。
on:
schedule:
- cron: '0 18 * * 2'
POSIXのcron構文と同じなので馴染みのある方もいらっしゃるかと思いますが、詳しくは公式ドキュメントを見てみてください。
おわり!
以上のプロジェクトをGithubにあげておけば設定したスケジュールでタスクが走るようになります。簡単ですね!
GithubActionsはドキュメントも整っていますし、簡単に使えて本当に便利ですよね。
おまけ
スクレイピングする際はいろいろと注意点があるので気をつけてください。刑事事件にもなっているので以下を読んでスクレイピングする際の不安感とリテラシーを身につけておきましょう。
以下にも目を通しておくと良いかと思います。