はじめに
amazon kindleで本を読んでいる方なら、highlight(強調線)を引くことがたまにあると思う。
rubyにおいてのkindle-highlights関連ライブラリは、スクレイピングするためにMechanizeを用いているが、 個別で本の情報を取り出そうとなるとasin(アマゾン独自の商品識別番号)が必要となる(多分)。これを改良したいと思い、コードを書いた。
スクレイピング用ライブラリとしてSeleniumを用いてkindleのhighlightを取り出すことが出来たので、皆さんの参考になればと考えている。今回は、すべての本のhighlightを取り出ところまで出来た。今後、書籍名か作者名だけで書籍を特定し、その書籍のhighlightだけを取り出すように改善したい。
早速ソースコード
require 'selenium-webdriver'
require 'dotenv'
Dotenv.load
EMAIL = ENV['KINDLE_ID']
PASSWORD = ENV['KINDLE_PW']
def main
#ドライバのインスタンスを生成
driver = Selenium::WebDriver.for :firefox
#urlを取り出す。
driver.get ENV['KINDLE_READ_URL']
#URLからemailとpasswordのボックス要素を取り出し、文字列を入力する。
email_box = driver.find_element(:name,'email')
email_box.send_key EMAIL
pwd_box = driver.find_element(:name, 'password')
pwd_box.send_key PASSWORD
#POSTを送るボタン要素を探し出しクリックする。
#サイトのHTMLに<form>..</form>要素が存在するなら、
# submitメソッドを使ってもよい。
#その際には、find_element(:xxxx,'formを識別できるclass、idなど')と使う。
#(多分)
driver.find_element(:id,'signInSubmit').click
#全ての本のseleniumインスタンス?を取得。
each_books = driver.find_elements(:class,'kp-notebook-library-each-book')
#ロード時間にドライバを操作させないためにWaitインスタンスを生成。
wait = Selenium::WebDriver::Wait.new(:timeout => 10)
book_hash = {}
each_books.each do |book|
text_array = []
#各々の本をクリックすることによって、そのハイライトを表示する。
book.click
#クリックされた後、ロード時間を待たないでfind_elementを使うと、
#以降の要素を操作することが出来ず、ElementNotInteractableError
#が発生する。
#そのために、h3タグ(書籍の題名)が操作可能になるまで待つ。
wait.until {driver.find_element(:tag_name, 'h3').enabled?}
#書籍名とテキストを取り出す。後者は配列。
book_title = driver.find_element(:tag_name,'h3')
highlights = driver.find_elements(:id,'highlight')
highlights.each do |highlight_text|
text_array << highlight_text.text
end
book_hash[book_title.text] = text_array
end
driver.quit
book_hash
end
puts main
このコードは実際、 wait.until {driver.find_element(:tag_name, 'h3').enabled?} 以外は極めて基本的である。上記されているように、この工程を行わないと、ロードされている間ドライバはh3タグを発見することが出来ないためエラーが出る。
#エラーが出るコード
book_title = driver.find_element(:tag_name,'h3') # <-ここでエラー
wait.until(book_title.enabled?)
出力
注意点
何度も繰り返すとamazonさんにばれて人しか認識できない文字の認証をしてくる。それでも繰り返すと利用規約も一緒にポップするので時間をおかなくてはならなくなる。
解決法はブラウザを閉じないこと。重くなるかもしれないが、なぜか何回もチャレンジできた。