質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.34%

pythonでJupiternotebookを利用したスクレイピング実装時に、スライダー部分の自動動作を行いたい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 385

shinnuko

score 13

Windows10
python3.7
Anaconda3
上記の開発環境でSelenium(Jupiternotebook)を使用しての宿泊予約サイトのスクレイピングを行っています。
※https://jp.hotels.com/

手順としてはトップページにアクセス→ログイン画面に移動→ログインパスワード自動入力(ログイン)
→検索条件の自動入力入力(各フォーム)という流れになります。

今問題が発生している部分は、検索条件の自動入力の項目にスライダー操作での料金設定を行う部分の動作が上手く実装できない状態です。

以下が現在のコードとエラー状況です。

pip install selenium

#ログイン画面へ遷移
from selenium import webdriver
from time import sleep
browser = webdriver.Chrome(executable_path="C:/Users/endes/work/chromedriver")
browser.get('https://jp.hotels.com/?intlid=SIGNIN+%3A%3A+header_main_section')
MAILADRESS = 'ログイン用アドレス'
PASSWORD = 'ログイン用パス'
error_flg = False
sleep(5)
try:
    login_button = browser.find_element_by_link_text('ログイン')
    login_button.click()
    sleep(1)
except:
    import traceback
    traceback.print_exc()

#メールアドレス_パスワードを入力→ログイン
if error_flg is False:
    try:
        mailadress_input = browser.find_element_by_xpath('//*[@id="sign-in-email"]')
        mailadress_input.send_keys(MAILADRESS)
        sleep(1)

        password_input = browser.find_element_by_xpath('//*[@id="sign-in-password"]')
        password_input.send_keys(PASSWORD)
        # ログインエラー時はパスの数字確認
        userlogin_button = browser.find_element_by_xpath('//*[@id="main-content"]/div/div/div/div/div/div[2]/form/button')
        userlogin_button.click()
        sleep(1)

    except:
        import traceback
        traceback.print_exc()

#場所指定→チェックイン日入力→チェックアウト日入力
from selenium.webdriver.common.keys import Keys
if error_flg is False:
    SEARCHLOCATION = '東京 赤坂'
    CHECKINDAY = '2020/04/29'
    CHECKOUTDAY = '2020/05/02'
    try:
        searchlocation_input = browser.find_element_by_xpath('//*[@id="qf-0q-destination"]')
        searchlocation_input.send_keys(SEARCHLOCATION)
        sleep(1)
        checkinday_input = browser.find_element_by_xpath('//*[@id="qf-0q-localised-check-in"]')
        browser.find_element_by_xpath('//*[@id="qf-0q-localised-check-in"]').send_keys(Keys.CONTROL + "a")
        browser.find_element_by_xpath('//*[@id="qf-0q-localised-check-in"]').send_keys(Keys.DELETE)
        checkinday_input.send_keys(CHECKINDAY)
        sleep(3)
        checkoutday_input = browser.find_element_by_xpath('//*[@id="qf-0q-localised-check-out"]')
        browser.find_element_by_xpath('//*[@id="qf-0q-localised-check-out"]').send_keys(Keys.CONTROL + "a")
        browser.find_element_by_xpath('//*[@id="qf-0q-localised-check-out"]').send_keys(Keys.DELETE)
        checkoutday_input.send_keys(CHECKOUTDAY)
        sleep(3)
    except:
        import traceback
        traceback.print_exc()

#大人人数の変更21
from selenium import webdriver
from selenium.webdriver.support.select import Select
if error_flg is False:
    try:
        element = browser.find_element_by_id("qf-0q-room-0-adults")
        #ここの数字は人数指定
        indexNum = 0
        select = Select(element)
        select.select_by_index(indexNum)
        sleep(1)  
    except:
        import traceback
        traceback.print_exc()

#検索ボタンをクリック→条件指定※Wifi_評価3以上に設定
if error_flg is False:
    try:
        search_button = browser.find_element_by_xpath('//*[@id="hds-marquee"]/div[2]/div[1]/div/form/div[4]/button')
        search_button.click()
        sleep(10)

        wifi_select = browser.find_element_by_xpath('//*[@id="f-popular-527"]')
        wifi_select.click()
        sleep(3)

        evaluation_select3 = browser.find_element_by_xpath('//*[@id="f-star-rating-3"]')
        evaluation_select3.click()
        sleep(3)

        evaluation_select4 = browser.find_element_by_xpath('//*[@id="f-star-rating-4"]')
        evaluation_select4.click()
        sleep(3)

        evaluation_select5 = browser.find_element_by_xpath('//*[@id="filter-price"]/div[2]/div/div[2]/div[3]')
        evaluation_select5.click()
        sleep(3)

    except:
        import traceback
        traceback.print_exc()

#料金設定_スライド操作対応
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
if error_flg is False:
    try:
        browser.implicitly_wait(10) 
        width = main_select.size["width"]
        height = main_select.size["height"]
        slider = browser.find_element_by_class_name("widget-slider-handle")
        move.click_and_hold(slider).move_by_offset(width/3, 0).release().perform()
        sleep(3)
    except:
        import traceback
        traceback.print_exc()


以下が検出されたエラーコードです

Traceback (most recent call last):
  File "<ipython-input-115-8058c2e7aa91>", line 10, in <module>
    move.click_and_hold(slider).move_by_offset(width/3, 0).release().perform()
  File "C:\Users\endes\Anaconda3\lib\site-packages\selenium\webdriver\common\action_chains.py", line 80, in perform
    self.w3c_actions.perform()
  File "C:\Users\endes\Anaconda3\lib\site-packages\selenium\webdriver\common\actions\action_builder.py", line 76, in perform
    self.driver.execute(Command.W3C_ACTIONS, enc)
  File "C:\Users\endes\Anaconda3\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "C:\Users\endes\Anaconda3\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
  (Session info: chrome=80.0.3987.122)


試したこと
下記の記事を参考に以下の内容で要素取得の待機を実装。
https://blog.ikappio.com/wait-for-elements-to-display-in-selenium-python3/

エラー内容を調査した所、捜査対象の要素を取得するまで待機をさせる必要があるのが判明し、以下の方法で実装しました。
こちらでも同じエラーが検出され、次にbrowser.implicitly_wait(10)での実装を試したという流れです。

#料金設定_スライド操作対応
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
if error_flg is False:
    try:
        wait = WebDriverWait(browser, 10)
        width = main_select.size["width"]
        height = main_select.size["height"]
        slider = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, '#filter-price > div:nth-child(3) > div > div.widget-slider-cont > div.cta.cta-control.widget-slider-handle.widget-slider-handle-max')))
        move.click_and_hold(slider).move_by_offset(width/3, 0).release().perform()
        sleep(3)
    except:
        import traceback
        traceback.print_exc()


こちらでも同じ内容がエラーとして検出されていました。

Traceback (most recent call last):
  File "<ipython-input-112-0217b877c140>", line 13, in <module>
    move.click_and_hold(slider).move_by_offset(width/3, 0).release().perform()
  File "C:\Users\endes\Anaconda3\lib\site-packages\selenium\webdriver\common\action_chains.py", line 80, in perform
    self.w3c_actions.perform()
  File "C:\Users\endes\Anaconda3\lib\site-packages\selenium\webdriver\common\actions\action_builder.py", line 76, in perform
    self.driver.execute(Command.W3C_ACTIONS, enc)
  File "C:\Users\endes\Anaconda3\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "C:\Users\endes\Anaconda3\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
  (Session info: chrome=80.0.3987.122)
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

ちゃんとプログラム読んでいなくて申し訳ないのですが、
これで解決できないでしょうか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/03/22 01:12

    返信遅れて申し訳ありませんでした。問題解決に至りましたので報告させて頂きます。
    今回はありがとうございました!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る