LoginSignup
shoukaiseki00
@shoukaiseki00

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

Chromeがheadlessにするとseleniumでエラーが起きる

解決したいこと

Seleniumで画面遷移した後の画面で要素が取得できない問題の解消.
selenium, headlessのchromeがうまく動かない。

例)
amazonにて、商品(Nintendo Switch)を自動で購入するプログラムをpythonで作成しています。
headlessのChromeでプログラムを実行すると、おそらくseleniumのelementでうまく要素を取れないといったエラーが発生します。
解決方法を教えて下さい。

発生している問題・エラー

Traceback (most recent call last):
  File "/Users/shigematsuhiroyasu/Desktop/python_switch/switch_buy.py", line 138, in <module>
    schedule.run_pending()
  File "/Users/name/opt/anaconda3/lib/python3.8/site-packages/schedule/__init__.py", line 592, in run_pending
    default_scheduler.run_pending()
  File "/Users/name/opt/anaconda3/lib/python3.8/site-packages/schedule/__init__.py", line 94, in run_pending
    self._run_job(job)
  File "/Users/name/opt/anaconda3/lib/python3.8/site-packages/schedule/__init__.py", line 147, in _run_job
    ret = job.run()
  File "/Users/name/opt/anaconda3/lib/python3.8/site-packages/schedule/__init__.py", line 491, in run
    ret = self.job_func()
  File "/Users/name/Desktop/python_switch/switch_buy.py", line 106, in switch
    p = driver.find_element_by_class_name('grand-total-price').text
  File "/Users/name/opt/anaconda3/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 564, in find_element_by_class_name
    return self.find_element(by=By.CLASS_NAME, value=name)
  File "/Users/name/opt/anaconda3/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 976, in find_element
    return self.execute(Command.FIND_ELEMENT, {
  File "/Users/name/opt/anaconda3/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "/Users/name/opt/anaconda3/lib/python3.8/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":".grand-total-price"}
  (Session info: headless chrome=89.0.4389.82)

該当するソースコード

import re
import sys
import time
import datetime
import requests
import schedule
from bs4 import BeautifulSoup
from datetime import datetime
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import chromedriver_binary
from selenium.webdriver.common.keys import Keys


#現在スイッチの在庫がないので、在庫があってかつamazon.co.jpが販売・発送を行う他の商品のリンクを使っています。
#Nintendo Switch
#ITEM_URL = 'https://www.amazon.co.jp/任天堂-【マリオ35周年キャンペーン対象】Nintendo-Switch-マリオレッド×ブルー-セット/dp/B08TMVTVJ2'

#テスト用 カセット
ITEM_URL = 'https://www.amazon.co.jp/%E4%BB%BB%E5%A4%A9%E5%A0%82-%E3%80%90%E3%83%9E%E3%83%AA%E3%82%AA35%E5%91%A8%E5%B9%B4%E3%82%AD%E3%83%A3%E3%83%B3%E3%83%9A%E3%83%BC%E3%83%B3%E5%AF%BE%E8%B1%A1%E3%80%91%E3%82%B9%E3%83%BC%E3%83%91%E3%83%BC%E3%83%9E%E3%83%AA%E3%82%AA-3D%E3%83%AF%E3%83%BC%E3%83%AB%E3%83%89-%E3%83%95%E3%83%A5%E3%83%BC%E3%83%AA%E3%83%BC%E3%83%AF%E3%83%BC%E3%83%AB%E3%83%89-Switch/dp/B08HH6K7P8/ref=sr_1_2?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=mario&qid=1615616026&s=videogames&sr=1-2'

LOGIN_EMAIL = '***'
LOGIN_PASSWARD = '***'
dt_now = datetime.now()
FINAL_BUY_CLASS = 'class="a-button-text place-your-order-button"'
LIMIT_PRICE = 33500

res = requests.get(ITEM_URL)
soup = BeautifulSoup(res.text, "html.parser")


def switch():
    #chrome を開く
    #driver = webdriver.Chrome('/Users/name/Downloads/chromedriver-2')
    options = Options()

    #options.binary_location = '/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary'
    options.add_argument('--headless') 
    options.add_argument('--disable-gpu')

    # headlessでは不要そうな機能
    options.add_argument('--disable-desktop-notifications')
    options.add_argument("--disable-extensions")
    driver = webdriver.Chrome(options=options)
    driver.implicitly_wait(300)

    # 画像を読み込まないで軽くする
    options.add_argument('--blink-settings=imagesEnabled=false')

    options.add_argument('--user-agent=hogehoge')

    #商品ページに飛ぶ
    driver.get(ITEM_URL)
    print(driver.current_url)


    #画面サイズ調節
    driver.set_window_position(0,0)
    driver.set_window_size(1440, 900)
    print('画面サイズ調節しました')



    #販売元確認
    shop = driver.find_element_by_id('merchant-info').text
    print(shop)
    shopp = re.sub('この商品は、', '', shop)
    shoppp = re.sub(' が販売、発送します。', '', shopp)
    print('この商品は' + shoppp + 'が販売、発送するそうです!')

    if shoppp == ("Amazon.co.jp"):
        print("転売じゃないので買う")
    else :
        print("転売なので買わない")
        sys.exit()


    #購入するボタンを押す
    buybutton = driver.find_element_by_id('buy-now-button')
    buybutton.click()

    print('購入ボタンを押しました')


    #ログインする
    #ログイン用メアドを入力する
    element = driver.find_element_by_id('ap_email')
    element.send_keys(LOGIN_EMAIL)
    element.send_keys(Keys.ENTER)
    print('ログイン用メアドを入力しました')



    #ログイン用パスワードを入力する
    print(driver.current_url)
    element = driver.find_element_by_id('ap_password')
    element.send_keys(LOGIN_PASSWARD)
    element.send_keys(Keys.ENTER)
    print('ログイン用パスワードを入力しました')
    print('ログイン完了しました')

    time.sleep(5)


    #値段確認
    print(driver.current_url)
    p = driver.find_element_by_class_name('grand-total-price').text
    print(p)
    pp = re.sub(',', '', p)
    ppp = re.sub('¥', '', pp)   
    print(ppp)

    if int(ppp) > LIMIT_PRICE :
        print("定価より高いから買わない")
        sys.exit()
    else :
        print("定価だから買う")
        pass    


    #購入確定ボタンを押す
    final_buy_button = driver.find_element_by_name("placeYourOrder1")
    final_buy_button.click()
    print('購入確定しました')
    print(dt_now)
    print(dt_now.strftime('%Y年%m月%d日 %H:%M:%S'))
    time.sleep(10)  


    #chrome終了
    driver.close()
    driver.quit()
    print('chromeを閉じました')


schedule.every(1).second.do(switch)

while True:
    schedule.run_pending()
    time.sleep(1)

自分で試したこと

headlessでより高速に動けば解決するかと考えて、'headless 高速化'などで調べて色々コードに書き加えました。
また、ページリンクを調べたところ、ログイン完了をしても、ページが変わっていないことが、print(driver.current_url)より、わかりました。そのせいでp = driver.find_element_by_class_name('grand-total-price').textがうまく動いていないことに気づきました。
そこで私は、time.sleep()やdriver.implicitly_wait(300)を使いましたがダメでした。
どうすれば解決するでしょうか?回答よろしくお願いします。

0

No Answers yet.

Your answer might help someone💌