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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

1206閲覧

waitによる待機で複数の要素をしている方法はありますでしょうか?

fuku-chann

総合スコア82

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2022/12/11 05:46

編集2022/12/13 22:47

Python Seleniumでスクレイピングするときに、下記コードのuntilによる待機を入れていますが、たまにエラーが出ている時があるため、調査すると、要素がうまく取得できていませんでした。

下記のコードでは、class xxxが取得できるまで待機を指示していますが、次の要素まで表示されていないタイミングで取得している時があるのではないかと懸念しております。

class名 + class名 + valueまで待機を指示するように書き換えることはできますでしょうか?

python

1element = wait.until(EC.visibility_of_all_elements_located((By.CLASS_NAME, "xxx")), message = "タイムアウト")

取得したい要素

python

1ex = driver.find_element_by_class_name("FPdoLc.lJ9FBc").find_element_by_class_name("gNO89b").get_attribute("value")

全文です

python

1from selenium.webdriver.support import expected_conditions as EC 2import inspect 3import traceback 4 5driver = webdriver.Firefox(executable_path=path, options=options) 6driver.implicitly_wait(15) 7wait = WebDriverWait(driver, 5) 8 9try: 10 driver.get("https://www.google.com/") 11 element = wait.until(EC.visibility_of_all_elements_located((By.CLASS_NAME, "xxx")), message = "タイムアウト") 12 ex = driver.find_element_by_class_name("FPdoLc.lJ9FBc").find_element_by_class_name("gNO89b").get_attribute("value") 13except Exception as e: 14 print(location(), e) 15 print(traceback.format_exc())

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

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

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

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

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

guest

回答1

0

ベストアンサー

untilには、待ちたい条件が満たされれれば真となるメソッドを渡すので、そういう関数を定義すれば良いかと思います。

Python

1def foo(driver): 2 x = driver.find_elements_by_class_name("xxx") 3 if len(x)>1: 4 y = x[1].find_elements_by_tag_name("a") 5 if len(y)>0: 6 return y[0] 7 return False 8 9ex = wait.until(foo , message = "タイムアウト")

とりあえず「存在するかどうか」だけチェックしていますが、追加でチェックが必要なら追加して下さい。

投稿2022/12/12 04:27

編集2022/12/13 13:47
otn

総合スコア84423

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

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

fuku-chann

2022/12/12 08:20 編集

素晴らしいご提案ありがとうございます。 下記falseが定義されていないというエラーができるのですが、どこを修正すればよろしいでしょうか? return falseを使ったことがないので、お手数ですが簡単にご説明もお願いいたします(m_ _m) また、下記はfoo(driver)ではなくfooになるのでしょうか? ex = wait.until(foo , message = "タイムアウト") ('test.py', 77) name 'false' is not defined Traceback (most recent call last): File "test.py", line 72, in <module> ex = wait.until(foo, message = "タイムアウト") File "/Users/mxxx/.pyenv/versions/3.6.0/lib/python3.6/site-packages/selenium/webdriver/support/wait.py", line 71, in until value = method(self._driver) File "test.py", line 68, in foo return false NameError: name 'false' is not defined Traceback (most recent call last): File "test.py", line 72, in <module> ex = wait.until(foo, message = "タイムアウト") File "/Users/mxxx/.pyenv/versions/3.6.0/lib/python3.6/site-packages/selenium/webdriver/support/wait.py", line 71, in until value = method(self._driver) File "test.py", line 68, in foo return false NameError: name 'false' is not defined
fuku-chann

2022/12/12 08:39 編集

下記に変更したらfalse定義のエラーは解決しました。 return False タイムアウトエラーが出ていましたので、下記に修正いたしました。 ex = wait.until(foo(driver) , message = "タイムアウト")
fuku-chann

2022/12/12 08:43

boolオブジェクトの呼び出しできないようです。 untilの行をコメントアウトしてsleepにすると要素は取得されておりますので、クラス名は問題ないと思います。 最後に現在のコードを記載しますので、原因分かりましたらご教示ください。 ('test.py', 79) 'bool' object is not callable Traceback (most recent call last): File "test.py", line 73, in <module> ex1 = wait.until(foo(driver), message = "タイムアウト") File "/Users/mxxx/.pyenv/versions/3.6.0/lib/python3.6/site-packages/selenium/webdriver/support/wait.py", line 71, in until value = method(self._driver) TypeError: 'bool' object is not callable Traceback (most recent call last): File "test.py", line 73, in <module> ex1 = wait.until(foo(driver), message = "タイムアウト") File "/Users/mxxx/.pyenv/versions/3.6.0/lib/python3.6/site-packages/selenium/webdriver/support/wait.py", line 71, in until value = method(self._driver) TypeError: 'bool' object is not callable def foo(driver): x = driver.find_elements_by_class_name("FPdoLc.lJ9FBc") if len(x)>1: y = x[0].find_elements_by_class_name("gNO89b") if len(y)>0: return y[0] return False try: driver.get("https://www.google.com/") # sleep(3) ex1 = wait.until(foo(driver), message = "タイムアウト") ex2 = driver.find_element_by_class_name("FPdoLc.lJ9FBc").find_element_by_class_name("gNO89b").get_attribute("value") print(location(), ex2) except Exception as e: print(location(), e, traceback.format_exc()) print(traceback.format_exc())
fuku-chann

2022/12/12 08:49 編集

xもyも要素が1つのようですが、その場合は下記になりますでしょうか? if len(x)>=1: def foo(driver): x = driver.find_elements_by_class_name("FPdoLc.lJ9FBc") print(location(), len(x)) if len(x)>=1: y = x[0].find_elements_by_class_name("gNO89b") print(location(), len(y)) if len(y)>0: return y[0] return False try: driver.get("https://www.google.com/") # sleep(3) ex1 = wait.until(foo(driver), message = "タイムアウト") ex2 = driver.find_element_by_class_name("FPdoLc.lJ9FBc").find_element_by_class_name("gNO89b").get_attribute("value") print(location(), ex2) except Exception as e: print(location(), e, traceback.format_exc()) print(traceback.format_exc())
otn

2022/12/12 11:49

Falseとfalseのタイプミス失礼しました。 > ex = wait.until(foo(driver) , message = "タイムアウト") 「待ちたい条件が満たされれれば真となるメソッドを渡す」の意味がわかりませんか? ex = wait.until(foo , message = "タイムアウト") ですね。と、回答に書いたのですが。 > xもyも要素が1つのようですが、 ?? driver.find_elements_by_class_name("xxx")[1] と書いてあったので、2つ以上あると思ったのですが?? 1つしかなかったら [1] という添え字はありません。 HTMLをよく見て、よく考えましょう。
fuku-chann

2022/12/12 23:04 編集

>driver.find_elements_by_class_name("xxx")[1] と書いてあったので、2つ以上あると思ったのですが?? 申し訳ございません。説明が間違っておりました。正しくは、「xもyも要素が1つの時もあり、今回例題で使った要素は1つになりますが、その場合は下記になりますでしょうか?」になります。 本文修正させていただきました。 >ex = wait.until(foo , message = "タイムアウト") ?ですね。と、回答に書いたのですが。 fooとfoo(driver)どちらが正しいのでしょうか?
otn

2022/12/13 02:50

回答に書いたコードは、修正前の最初の質問の、 > 取得したい要素 > ex = driver.find_elements_by_class_name("xxx")[1].find_elements_by_tag_name("a")[0] に対応しいたサンプルなので、取得したい要素がこれと違うなら、対応して修正しましょう。 > fooとfoo(driver)どちらが正しいのでしょうか? ex = wait.until(foo , message = "タイムアウト") と2回書いて(これで3回目) ex = wait.until(foo(driver) , message = "タイムアウト") と書いたことは一度も無いのですが、何故、 ex = wait.until(foo(driver) , message = "タイムアウト") と書いたのでしょうか?うっかりミスなら、修正しましょう。
fuku-chann

2022/12/13 08:24

いくつかエラーがあって混乱していました。 この関数は今後役に立ちそうです。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問