前回のおさらい
Chromeのプロファイルパスに事前にセッションを持つことで無事に画像認証を突破してSelenium+Pythonでのスクレイピングができるようになりました。
https://qiita.com/shioharu_/items/225f38c23a652459962f
質問で「ログインを事前に行ってセッションをあらかじめ持っておく方法でしたっけ?」と確認があったので、
今回は事前にログインせず画像認証のところだけのみ手動ログインして行う待機処理の方法でスクレイピングを実施します。
待機処理
「5. 待機 - Selenium Python Bindings 2 ドキュメント」
明示的な待機
5.1. 明示的な待機
明示的待機とは、特定の条件が発生するのを待ってからコードを進めるコードです。これの最悪の場合は、time.sleep()であり、条件を待機する正確な時間に設定します。必要な時間だけ待つコードを書くのに役立つ便利なメソッドがいくつか用意されています。WebDriverWaitとExpectedConditionを組み合わせることで、これを実現できます。
ふむふむ。ではまず最悪の場合をやってみましょう。
明示的な待機サンプルソース
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time
options = Options()
options.add_argument('--no-sandbox')
options.add_argument('--disable-gpu')
options.add_argument('--window-size=1280,1024')
driver = webdriver.Chrome(options=options)
driver.get('https://p.eagate.573.jp/game/2dx/27/ranking/weekly.html')
time.sleep(120) # この間にログインを行う
driver.find_element_by_xpath("/html/body/div/div[1]/div/div/div[2]/div/div[2]/form/div[2]/ul[1]/li[3]/input").click()
time.sleep(3)
driver.execute_script("window.scrollTo(0, 800)")
time.sleep(3)
driver.save_screenshot('sample.png')
driver.quit()
確かに実現できました。
しかし、当たり前ですが早くログイン出来たら待ち時間がありますし、もし時間内にログインできなかったら不発になります。
効率が悪くなってしまいますね(-_-;)
暗黙の待機
5.2. 暗黙の待機
暗黙の待機はすぐに利用できない要素(または複数要素)を見つけようとする時、WebDriverにDOMを一定時間ポーリングするように指示します。デフォルトの設定は0です。一度設定されると、暗黙の待機がWebDriverオブジェクトの有効期間に設定されます。
from selenium import webdriver
driver = webdriver.Firefox()
driver.implicitly_wait(10) # seconds
driver.get("http://somedomain/url_that_delays_loading")
myDynamicElement = driver.find_element_by_id("myDynamicElement")
というものがありました。
つまるところ、
- 暗黙の待機を利用したスクレイピングを行う。
- ログインが必要な画面は、まだログインされてないのでログインしてください画面に飛ぶ。
- 暗黙の待機により待機時間中はログインしない限りログイン後の要素を探し続ける。
- 待機されている画面でログインを行う。
- ログイン後の要素を発見し後続の動作を実行する。
といった具合になるはず、ということです。
やってみましょう。
暗黙の待機サンプルソース
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time
options = Options()
options.add_argument('--no-sandbox')
options.add_argument('--disable-gpu')
options.add_argument('--window-size=1280,1024')
driver = webdriver.Chrome(options=options)
driver.implicitly_wait(120)
driver.get('https://p.eagate.573.jp/game/2dx/27/ranking/weekly.html')
driver.find_element_by_xpath("/html/body/div/div[1]/div/div/div[2]/div/div[2]/form/div[2]/ul[1]/li[3]/input").click()
driver.find_element_by_xpath("/html/body/div/div[1]/div/div/div[2]/div/div[7]/table/tbody/tr[201]/td[8]")
driver.execute_script("window.scrollTo(0, 800)")
driver.save_screenshot('sample.png')
driver.quit()
実現できました!!!
総評
- 無事、事前ログインせずとも画像認証を突破することができました。
- 思ったよりもお手軽にできたのでSelenium Python Bindings のドキュメントはよく読もうと思いました。