Madogiwa Blog

主に技術系の学習メモに使っていきます。

Ruby:seleniumを使って動的ページをスクレイピングしてみる

以前、Nokogiriを使ったスクレイピングについてブログを書きましたが、JavaScriptで初期表示時にページを動的に変更しているページ等上手く値を取得するこが出来ません。。。
※httpレスポンスに設定されたHTMLを取得しているため

madogiwa0124.hatenablog.com

動的ページのスクレイピングには、Webブラウザでの操作を自動化できるseleniumが便利です。

github.com

はじめに

今回は、Google翻訳の結果をスクレイピングするツールを作ったので、それをもとにseleniumの使い方を書いていきます。 ちなみにソースコードRubyです。

使い方

環境構築

seleniumを使うのに必要なのは、selenium用のgemとWebDriverです。今回はGoogleChromeのドライバをインストールしてます。

# selenium用のgemをインストール
$ gem install selenium-webdriver
# Chrome用のドライバをインストール
$ brew install chromedriver

これで準備完了です!

実際にスクレイピングしてみる

スクレイピングの基本的な手順は、下記の通りです。

  1. ドライバーの起動
  2. URLへアクセス
  3. 要素を取得

実際にGoogle翻訳の結果を取得するソースコードが以下のものです。

# Google翻訳にアクセスして、翻訳結果を取得
# target_lang:翻訳前言語、result_lang:翻訳後言語、word:翻訳対象文字列
def get_translate_result(target_lang, result_lang, word)
  # URL生成
  url = "#{GOOGLE_TRANSLATE_URL}##{target_lang}/#{result_lang}/#{word}"
  # ドライバーの起動
  driver = Selenium::WebDriver.for :chrome
  # URLへアクセス
  driver.navigate.to(url)
  # タイムアウト値の設定
  wait = Selenium::WebDriver::Wait.new(timeout: 10)
  begin
    # タイムアウトになるまで、翻訳結果部からテキスト情報を取得
    wait.until{ html = driver.find_element(id: 'result_box'); html.text }
  rescue RuntimeError => e
    # ERROR処理、メッセージを出力してドライバーを終了
    puts e.message
    driver.quit
  end
end

ヘッドレスブラウザを使ってみる

ヘッドレスブラウザを使うと、ブラウザを起動せずにスクレイピングを行うことができます。
先程のソースコードをヘッドレスブラウザを使用するように書き替えたものが以下です。

# Google翻訳にアクセスして、翻訳結果を取得
def get_translate_result(target_lang, result_lang, word)
  # URL生成
  url = "#{GOOGLE_TRANSLATE_URL}##{target_lang}/#{result_lang}/#{word}"
  # オプションの生成(ヘッドレスブラウザで動作するように)
  options = Selenium::WebDriver::Remote::Capabilities
  options = options.chrome('chromeOptions' => { args: ['--headless'] })
  # ドライバーの起動
  driver = Selenium::WebDriver.for :chrome, desired_capabilities: options
  # URLへアクセス
  driver.navigate.to(url)
  # タイムアウト値の設定
  wait = Selenium::WebDriver::Wait.new(timeout: 10)
  begin
    # タイムアウトになるまで、翻訳結果部からテキスト情報を取得
    wait.until{ html = driver.find_element(id: 'result_box'); html.text }
  rescue RuntimeError => e
    # ERROR処理、メッセージを出力してドライバーを終了
    puts e.message
    driver.quit
  end
end

ソースコードの完全版は下記です。

github.com

参考

qiita.com

qiita.com