はじめに
pythonでSeleniumを遊び半分で触っていて発生したエラー第一弾です。
前回までのあらすじ
PythonでChromeDriverを操作してyoutubeの特定の画面へ遷移し、条件に合ったyoutube動画の情報をスクレイピングするコードを紹介しました。
今回発生したエラー
下記のコード実行中に発生
# ChromeDriverでurlを起動
driver = webdriver.Chrome(CHROME_DRIVER_PATH)
driver.get(url)
xpath = '//*[@id="tabsContent"]/tp-yt-paper-tab[2]'
driver.find_element_by_xpath(xpath).click()
エラー内容としては以下
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[@id="tabsContent"]/tp-yt-paper-tab[2]"}
xpathのクリック処理が入っているのにpathが見つからねーよと言われています
原因はwebページの読み込みが完了していない状態でxpathを探しに行っているためです。。。
ということでwebページの読み込みが完了するまで待機処理を追加する必要があります。
解決案検討(待機処理をいくつか)
time.sleep()
まずは単純に待機する方法としてtime.sleep()を試してみましょう
# ChromeDriverでurlを起動
driver = webdriver.Chrome(CHROME_DRIVER_PATH)
driver.get(url)
# 3秒待機
time.sleep(3)
xpath = '//*[@id="tabsContent"]/tp-yt-paper-tab[2]'
driver.find_element_by_xpath(xpath).click()
自分の環境ではこれでも問題なく動作しますが結論あまり良くありません。
なぜなら3秒間で読み込みが完了するということを保証するものではないからです。
implicitly_wait()
次に要素が見つかるまで待機する方法です
# ChromeDriverでurlを起動
driver = webdriver.Chrome(CHROME_DRIVER_PATH)
driver.get(url)
# 最大10秒待機
driver.implicitly_wait(10)
xpath = '//*[@id="tabsContent"]/tp-yt-paper-tab[2]'
driver.find_element_by_xpath(xpath).click()
上記の場合、xpathが見つかるまで最大10秒の待機処理が入ります。
もし10秒以内に見つかれば以降待機されることはないし、見つからないまま10秒経つとタイムアウトします
until
最後にwebコンテンツが全て読み込まれるまで待機する方法です。
# ChromeDriverでurlを起動
driver = webdriver.Chrome(CHROME_DRIVER_PATH)
driver.get(url)
# 全てのコンテンツが読み込まれるまで待機
try:
# 全てのコンテンツが読み込まれるまで待機
WebDriverWait(driver, 10).until(expected_conditions.presence_of_all_elements_located)
except TimeoutException:
# 例外処理
xpath = '//*[@id="tabsContent"]/tp-yt-paper-tab[2]'
driver.find_element_by_xpath(xpath).click()
個人的にはimplicitly_wait()かこの方法が有力なのかなという予想です(python初学者なので自信なし。。。)
presence_of_all_elements_locatedがloadされるまで最大10秒待機する方法です.
読み込みが完了していない場合はtry/catchでTimeoutExceptionをcatchしています
まとめ
待機処理って色々あるんだなーという感想
スクレイピングならこの方法という話であって、用途によって使い分けられるようになるといいですね