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

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

新規登録して質問してみよう
ただいま回答率
85.48%
スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

JupyterLab

JupyterLabは、Jupyter notebookの後継の対話型開発環境(IDE)です。データの可視化がインタラクティブで、プラグイン作成により新しいコンポーネントの追加および既存のコンポーネントも統合可能。サーバに閉じているため、データ分析に向いています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

selenium

Selenium(セレニウム)は、ブラウザをプログラムで作動させるフレームワークです。この原理を使うことにより、ブラウザのユーザーテストなどを自動化にすることができます。

Q&A

解決済

1回答

2508閲覧

selenium 入力ボックスの要素が見つからない

shin_qqq

総合スコア5

スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

JupyterLab

JupyterLabは、Jupyter notebookの後継の対話型開発環境(IDE)です。データの可視化がインタラクティブで、プラグイン作成により新しいコンポーネントの追加および既存のコンポーネントも統合可能。サーバに閉じているため、データ分析に向いています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

selenium

Selenium(セレニウム)は、ブラウザをプログラムで作動させるフレームワークです。この原理を使うことにより、ブラウザのユーザーテストなどを自動化にすることができます。

0グッド

1クリップ

投稿2023/01/18 14:05

編集2023/01/18 14:06

前提

閲覧頂きありがとうございます。

為替レートの情報を自動で取得したく
スクレイピングを試みています。

下記のサイトでCookieの同意をクリックした後、
「」の項目に入力するため要素の取得をしたいのですが、
要素が見つからずエラーとなります。

■対象ページ
https://usa.visa.com/support/consumer/travel-support/exchange-rate-calculator.html

発生している問題・エラーメッセージ

--------------------------------------------------------------------------- NoSuchElementException Traceback (most recent call last) Cell In[13], line 1 ----> 1 irame = browser.find_element(By.XPATH, '//*[@id="input_amount_paid"]') File ~\AppData\Local\Programs\Python\Python311\Lib\site-packages\selenium\webdriver\remote\webdriver.py:861, in WebDriver.find_element(self, by, value) 858 by = By.CSS_SELECTOR 859 value = '[name="%s"]' % value --> 861 return self.execute(Command.FIND_ELEMENT, {"using": by, "value": value})["value"] File ~\AppData\Local\Programs\Python\Python311\Lib\site-packages\selenium\webdriver\remote\webdriver.py:444, in WebDriver.execute(self, driver_command, params) 442 response = self.command_executor.execute(driver_command, params) 443 if response: --> 444 self.error_handler.check_response(response) 445 response["value"] = self._unwrap_value(response.get("value", None)) 446 return response File ~\AppData\Local\Programs\Python\Python311\Lib\site-packages\selenium\webdriver\remote\errorhandler.py:249, in ErrorHandler.check_response(self, response) 247 alert_text = value["alert"].get("text") 248 raise exception_class(message, screen, stacktrace, alert_text) # type: ignore[call-arg] # mypy is not smart enough here --> 249 raise exception_class(message, screen, stacktrace) NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[@id="input_amount_paid"]"} (Session info: chrome=109.0.5414.75) Stacktrace: Backtrace: (No symbol) [0x00806643] (No symbol) [0x0079BE21] (No symbol) [0x0069DA9D] (No symbol) [0x006D1342] (No symbol) [0x006D147B] (No symbol) [0x00708DC2] (No symbol) [0x006EFDC4] (No symbol) [0x00706B09] (No symbol) [0x006EFB76] (No symbol) [0x006C49C1] (No symbol) [0x006C5E5D] GetHandleVerifier [0x00A7A142+2497106] GetHandleVerifier [0x00AA85D3+2686691] GetHandleVerifier [0x00AABB9C+2700460] GetHandleVerifier [0x008B3B10+635936] (No symbol) [0x007A4A1F] (No symbol) [0x007AA418] (No symbol) [0x007AA505] (No symbol) [0x007B508B] BaseThreadInitThunk [0x76A100F9+25] RtlGetAppContainerNamedObjectPath [0x77747BBE+286] RtlGetAppContainerNamedObjectPath [0x77747B8E+238]

該当のソースコード

Python

1!pip install selenium 2from selenium import webdriver 3!pip install webdriver_manager 4from time import sleep 5 6from webdriver_manager.chrome import ChromeDriverManager 7 8from selenium.webdriver.common.by import By 9 10elem_ok_btn = browser.find_element(By.XPATH, '//*[@id="CookieReportsBanner"]/div[1]/div[2]/a[1]') 11elem_ok_btn.click() 12 13#エラー箇所↓↓ 14irame = browser.find_element(By.XPATH, '//*[@id="input_amount_paid"]')

試したこと

※XPATH、chras名などで指定しようと試みましたが、
いずれもエラーになります。

※iframeが使用されている場合は
htmlを確認しましたが、該当箇所ではframeは
使用されていないのか、同様にエラーとなりました。

補足情報(FW/ツールのバージョンなど)

Python 3.11.1 
selenium 4.7.2

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

該当のページは、cloudflare の cdn を利用してデータを取得しています。そのため、ページのロードを待つ必要がありそうです。

selenium でページロードを待機するには、.implicitly_wait() というメソッドを使います。

追記:加えて、該当の要素は Shadow DOM となっており、shadow root が設定されている内側にある要素です。そのため、shadow root を取得してから、任意の要素を取得するようにすれば上手く取得できます。

参照:Using shadow DOM - Web Components | MDN

python

1from selenium import webdriver 2 3browser = webdriver.Chrome() 4 5# ページ遷移時すぐに要素が見つからない場合に見つかるまで待機する時間を設定 6# この場合、10 秒までは要素が見つかるまで待ちます。それでも見つからないと諦めてタイムアウトを返します 7browser.implicitly_wait(10) 8 9browser.get(https://usa.visa.com/support/consumer/travel-support/exchange-rate-calculator.html) 10 11# Shadow root を持つ要素は、dm-calculator であることがわかるため、その要素のプロパティから shadowroot を取得します 12# その上で、任意の要素を取得します 13amount = browser.find_element( 14 By.XPATH, "//dm-calculator" 15).shadow_root.find_element(By.ID, "input_amount_paid") 16

より明示的な待機についてはドキュメントをご覧ください。

PlayWright を使った場合

selenium だと該当の要素の取得がどうにもうまくいかなかったため、試しに playwright でスクレイピングしてみたところ簡単に取得できたため、一応回答として残しておくことにします。

python

1import asyncio 2 3from playwright.async_api import async_playwright 4 5url = ( 6 "https://usa.visa.com/support/consumer/travel-support/" 7 "exchange-rate-calculator.html" 8) 9amount = "58742" 10 11 12async def main(): 13 async with async_playwright() as p: 14 browser = await p.chromium.launch() 15 page = await browser.new_page() 16 await page.goto(url) 17 await page.get_by_placeholder("Enter amount").fill(amount) 18 19 await page.get_by_role( 20 "button", name="Open from currency list drop down menu." 21 ).click() 22 await page.locator("#listbox-item-2").click() 23 await page.get_by_role( 24 "button", name="Open to currency list drop down menu." 25 ).click() 26 await page.locator("#listbox-item-0").click() 27 28 await page.get_by_role("button", name=" Calculate Conversion ").click() 29 30 print(await page.locator("h2.vs-h2").nth(1).text_content()) 31 print(await page.locator("dm-calculator div").nth(45).text_content()) 32 33 await browser.close() 34 35 36asyncio.run(main()) 37

投稿2023/01/19 06:00

編集2023/01/23 11:02
Demerara

総合スコア397

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shin_qqq

2023/01/19 13:13

早速のご回答頂きありがとうございました。 ご教示頂いた.implicitly_wait()を使用してみましたが、同様にNoSuchElementExceptionとなりました。 他に想定される原因などがあればご教示頂けますでしょうか。 ``` browser.implicitly_wait(10) Amount = browser.find_element(By.XPATH, '//*[@id="input_amount_paid"]') ```
Demerara

2023/01/20 06:39

該当の要素は iframe でしたね。失礼しました。 そうなると、ドキュメントの以下の内容が役に立ちそうです。 https://www.selenium.dev/ja/documentation/webdriver/interactions/frames/#name%E3%81%BE%E3%81%9F%E3%81%AFid%E3%82%92%E4%BD%BF%E3%81%86 ```python browser.switch_to.frame('input_amount_paid') iframe = browser.find_element(By.TAG_NAME, 'input') # iframe に対する処理 # 処理が終わったら元の状態に戻す browser.switch_to.default_content() ```
shin_qqq

2023/01/22 10:48

追加のアドバイス頂きありがとうございます。 頂いたように下記で試したところ、 やはりエラーとなります。 iframeの使われ方が特殊なのでしょうか、、? ```python browser.switch_to.frame('input_amount_paid') iframe = browser.find_element(By.TAG_NAME, 'input') ``` ↓エラーメッセージ NoSuchFrameException: Message: input_amount_paid
Demerara

2023/01/22 14:47

色々と試行錯誤してみましたが、私にはこの要素を selenium で取得することは出来ませんでした。お力になれず申し訳ありません。 selenium でのこの要素の取得が難しい理由はいくつか考えられますが、何が直接の原因なのかは私には判断できませんでした。また、複雑な手順を踏めば selenium でも該当の要素の取得が可能である可能性はあります。 つきましては、代替手段として別のスクレイピングツール PlayWright を利用した要素の取得方法を回答欄に追記いたしましたので、もし selenium にこだわらないのであれば、そちらのコードを参考にしていただければと思います。 もちろん、このまま別の方の回答を待っていただいても結構です。
Demerara

2023/01/23 10:55

何度もすみません。selenium でもできました。取得したい要素を開発者ツールで再度確認したところ Shadow DOM となっていることがわかりました。 その場合、その親要素を取得して shadow root を取得、その中の要素を取得するようにすれば上手く取得できます。回答を改めます。
shin_qqq

2023/01/29 08:24

ご回答ありがとうございました。 shadow rootを取得する方法で上手くいきました。 対象項目への記入もできたため次のステップへ進めています。 この度は何度も解決策をご教示頂き、ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問