はじめに
今回は連載企画第2回目ということで、スクレイピングについて書いていこうと思います。
これまでに書いた記事はこちら
gemの導入
まずはじめに、gemを導入します。
以下の記述をgemfileに追加してください。
また、seleniumはRSpecで通常使用するものになりますので、group :test do ~ end
のブロックの中にすでに記載がある場合はブロック外に記載を移すようにしてください。
# selenium
gem 'selenium-webdriver'
上記を記載しましたらbundle install
を実行してください。
ChromeDriverとChormeのインストール
次にスクレイピングをする際に、使用するwebブラウザを導入していきます。
以下のコマンドを使用するか、公式サイトからChromeをインストールしてください。
sudo apt update
sudo apt upgrade
wget --version
wgetがインストールされていない場合は「sudo apt install wget」を実施
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo dpkg -i google-chrome-stable_current_amd64.deb
インストール中にエラーが発生したら「sudo apt-get install -f」を実施してエラーを修復
google-chrome
上記コマンドを入力してChromeが起動すればインストール成功です。
ChromeDriverのインストール
brew install chromedriver
上記の設定が完了しましたら、ローカルマシン上でスクレイピングする準備が整いました。
(余談)selenium公式のDockerimageを使う
余談ですが、selenium公式がブラウザとドライバーを内包したコンテナイメージを提供してくれています。
aws上などでスクレイピングを動かすなどを想定しているのであればこちらの方が環境構築の面で行いやすいかと思います。
chrome:
image: seleniarm/standalone-chromium
ports:
- 4444:4444
- 7900:7900 #7900番ポートにアクセスするとRSpecのように自動制御されているブラウザが確認できます。
shm_size: "2gb"
tty: true
注意点
m1以降のarmアーキテクチャのmacをお使いの場合はimage:seleniarm/standalone-chromium
を使用してください。
chromeをDocker上で稼働させようとするとgoogle公式が提供しているブラウザでは対応していないためです。
intel製チップを搭載のmacであったり、amdアーキテクチャ搭載のマシンにつきましてはimage: selenium/standalone-chrome
で大丈夫です。
seleniumで使用するdriverの構築を行う。
ここからは実際にdriverを作成してスクレイピングを行う処理を書いていきます。
スクレイピングを組み込みたい部分に書いてください。
今回はActiveJobに書いていきます。
require "selenium-webdriver"
class SeleniumJob < ApplicationJob
queue_as :default
def perform(*args)
@wait_time = 10
@timeout = 180
Selenium::WebDriver.logger.output = File.join("./", "selenium.log")
Selenium::WebDriver.logger.level = :warn
options = Selenium::WebDriver::Chrome::Options.new
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
options.add_argument('--window-size=1280x800')
ua = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36'
options.add_argument("--user-agent=#{ua}")
@driver = Selenium::WebDriver.for :remote, url: 'http://chrome:4444/wd/hub', capabilities: [:chrome], options: options
@driver.manage.timeouts.implicit_wait = @timeout
wait = Selenium::WebDriver::Wait.new(timeout: @wait_time)
〜以下省略〜
performメソッド内にdriverの設定を記載しています。
-
@timeout
と@wait_time
については探しているhtml要素が見つからない時に何秒待つかを設定しています。 -
options
ではブラウザの設定を追加しています。-
--headless
はブラウザを立ち上げないで実行するオプションで、GUIを持たないマシンでも動作できるようにしてくれます。awsでは必須です。 -
--no-sandbox
はsandboxモードを解除します。 -
--disable-dev-shm-usage
はクラッシュする確率を減らします。 -
--window-size=1280x800
はウインドウサイズを1280×800に固定します。レスポンシブ対応しているブラウザで要素を見つけ出せないという事態を予防するために設定しています。 -
--user-agent=#{ua}
はuaという変数に格納されている情報にユーザエージェントを書き換えます。これにより自動制御プログラムでスクレイピングしているという情報を相手のサーバに対して隠すことができます。
-
-
Selenium::WebDriver.for :remote, url: 'http://chrome:4444/wd/hub', capabilities: [:chrome], options: options
について-
:remote, url: 'http://chrome:4444/wd/hub'
でリモート環境にあるブラウザを制御できるようにしています。Dockerの場合はこちらで行ってください。Docker以外の場合はこの箇所を:chrome
としてください。 -
capabilities: [:chrome]
では使用するdriverを指定しています。公式ではdesired_capabilities:
となっていますが、自分の環境では動作しなかったため今後推奨されるこちらを使用しております。
-
ここまでで、driverの構築と設定が完了しました。
作成したdriverを用いて実際にスクレイピングをしてみる。
今回はdriverに使えるメソッドを紹介しますので、実際に動かしてみてください。
-
driver.get(url)
urlで指定したサイトに遷移します。 -
driver.find_element(:html要素 指定するもの)
表示されたwebページの中から指定されたhtml要素を探し、最初の1つ目を返します。なければエラーを返します。 -
driver.find_elements(:html要素 指定するもの)
表示されたページの中から指定されたhtml要素を探し、配列に格納して返します。1つもない場合、エラーになりません。そのため、if文を使って分岐処理を書けます。 -
driver.submit
find_elementで見つけてきたsubmitボタンを押します。 -
driver.click
find_elementで見つけたsubmitやリンクをクリックします。 -
driver.title
webページのタイトルを取得します。
このメソッド以外にもたくさん使用できるものはありますので、以下の公式サイトを確認してみてください。
https://www.seleniumqref.com/api/webdriver_abc_ruby.html
終わりに
いかがでしたでしょうか。
連載企画第2回となる今回はseleniumを用いたスクレイピングをRubyで実行するというものでした。
特に私の環境特有のものかもしれませんが、公式リファレンスに書かれているdesired_capabilities:
を使用してドライバーを作成する際にそんなものないよとエラーになってしまい非常に苦労しましたので、同じエラーの方は少しでも参考になれば幸いです。
次回書くとしたら、AWSとDockerあたりかな〜とふんわり考えています。
その際はどうぞお付き合いをお願いいたします。
参考文献
https://www.seleniumqref.com/api/webdriver_abc_ruby.html
https://www.selenium.dev/ja/documentation/
https://zenn.dev/usmoo/articles/133bb9ab4864d7
https://morizyun.github.io/web/selenium-cheat-sheet.html
https://qiita.com/rubys8arks/items/84acba9171d215053b24
https://qiita.com/y-agatsuma/items/ea2c9845ee0a931d5c9c
https://github.com/SeleniumHQ/selenium/tree/trunk/rb
https://github.com/seleniumhq-community/docker-seleniarm