前提
BASEのログイン画面をseleniumでスクレイピングしているコードが
ローカルでは問題なく実行できるのですが、
該当のコードをHTTPトリガーでGCPにデプロイして、
トリガーURLをPOSTリクエストするとタイトルのエラーになります。
(デプロイ自体は問題なくできます。)
実現したいこと
- 本番環境で実行させたい
発生している問題・エラーメッセージ
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"id","selector":"UserMailAddress"}
該当のソースコード
python
1import os 2import shutil 3import stat 4import tempfile 5import time 6import urllib.parse 7from functools import reduce 8from pathlib import Path 9from dotenv import load_dotenv 10from pyexpat.errors import codes 11 12import chromedriver_binary 13from selenium import webdriver 14from selenium.webdriver.chrome.options import Options 15from selenium.webdriver.chrome.service import Service 16from selenium.webdriver.common.by import By 17from selenium import webdriver 18 19 20# 自動的にURLより認可コードを取得して返す 21def main(request): 22 23 POST_TOKEN_URL = "https://api.thebase.in/1/oauth/token" 24 GRANT_TYPE_AUTHCODE = "authorization_code" 25 26 # 認可コードの取得先URL 27 GET_AUTH_URL = ( 28 "https://api.thebase.in/1/oauth/authorize?response_type=" 29 "code&client_id=%ID%&redirect_uri=%URI%&scope=%SCOPE%" 30 ) 31 32 load_dotenv() 33 34 # BASEAPIで申請したclient_id 35 CLIENT_ID = os.getenv("CLIENT_ID") 36 37 # BASEAPIで設定したコールバックURL 38 APP_URL = os.getenv("APP_URL") 39 40 # アクセスURLの作成 41 auth_url = GET_AUTH_URL.replace("%ID%", f"{CLIENT_ID}") 42 auth_url = auth_url.replace("%URI%", urllib.parse.quote(f"{APP_URL}", safe="")) 43 auth_url = auth_url.replace("%SCOPE%", urllib.parse.quote("read_users read_orders")) 44 45 chrome_options = webdriver.ChromeOptions() 46 47 chrome_options.add_argument('--headless') 48 chrome_options.add_argument('--disable-gpu') 49 chrome_options.add_argument('--window-size=1280x1696') 50 chrome_options.add_argument('--no-sandbox') 51 chrome_options.add_argument('--hide-scrollbars') 52 chrome_options.add_argument('--enable-logging') 53 chrome_options.add_argument('--log-level=0') 54 chrome_options.add_argument('--v=99') 55 chrome_options.add_argument('--single-process') 56 chrome_options.add_argument('--ignore-certificate-errors') 57 58 time.sleep(5) 59 60 chrome_options.binary_location = os.getcwd() + "/bin/headless-chromium" 61 62 driver = webdriver.Chrome( 63 os.getcwd() + "/bin/chromedriver", chrome_options=chrome_options) 64 65 time.sleep(5) 66 driver.get(auth_url) 67 68 # ログインIDを入力 69 # 検索テキストボックスの要素をname属性値から取得 70 login_id = driver.find_element(By.CSS_SELECTOR, "input#UserMailAddress") 71 time.sleep(3) 72 mail = os.getenv("MAIL") 73 login_id.send_keys(mail) 74 75 # パスワードを入力 76 password = driver.find_element(By.CSS_SELECTOR, "input#UserPassword") 77 time.sleep(3) 78 pas = os.getenv("PASS") 79 password.send_keys(pas) 80 print(driver.page_source) 81 82 # ログインボタンをクリック 83 login_btn = driver.find_element(By.CLASS_NAME, "submitBtn") 84 login_btn.click() 85 86 time.sleep(3) 87 # URLから認可コードの抽出 88 tmp = driver.current_url.split("=")[1] 89 code = tmp.split("&")[0] 90 91 # 全てのウインドウとドライバーの終了 92 driver.quit() 93 time.sleep(2) 94 print("実行できた!") 95 print(code) 96 97 return code
試したこと
・Chromeとchromedriverのバージョンが同じか確認済み
・print(driver.page_source)でiframeがないか確認→なし
指定の仕方を変更してみた(ローカルでは問題なく実行できました。)
・driver.find_element(By.CSS_SELECTOR, "input#UserMailAddress")
→ エラー:
no such element: Unable to locate element: {"method":"css selector","selector":"input#UserMailAddress"}
・driver.find_element(By.NAME, "data[User][mail_address]")
→エラー:
no such element: Unable to locate element: {"method":"name","selector":"data[User][mail_address]"}
補足情報(FW/ツールのバージョンなど)
※上記のソースコードのままではローカルで動きません。
ローカルで実行確認する際は下記の削除をしてます。
・main関数の引数に入れているrequestを削除
・chromedriverとheadless-chromiumのパス削除
デプロイ時の使用コマンド (HTTPトリガー)
gcloud functions deploy test --entry-point main --trigger-http --timeout 540 --memory 512 --runtime python39 --allow-unauthenticated
参考にしたサイト
https://hacknote.jp/archives/51263/
https://tkstock.site/2022/06/14/python-selenium-developpertool-no-such-a-element/#web
ご教授いただけますと幸いです。
よろしくお願いいたします!

回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。