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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Firefox

Mozilla Foundationによって作られた無料、オープンソース、クロスプラットフォームなウェブブラウザ

Python 3.x

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

selenium

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

Q&A

解決済

1回答

382閲覧

Python seleniumでEC.visibility_of_all_elements_locatedがエラーになる

fuku-chann

総合スコア82

Firefox

Mozilla Foundationによって作られた無料、オープンソース、クロスプラットフォームなウェブブラウザ

Python 3.x

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

selenium

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

0グッド

0クリップ

投稿2023/05/21 23:32

現在のコードでsleep(8)の後にpタグを取得していますが、主にネットワークが遅い時にpタグが取得できずエラーが出てしまいます。改善コードのようにwait.until(EC.visibility_of_all_elements_located((By.TAG_NAME, "p")))を使ってpタグが全て取得されるまで待機したいのですが、この行でエラーになります。エラーメッセージが空白のため原因が特定に苦戦しています。

現在のコード

Python

1from selenium.webdriver.support.ui import WebDriverWait 2from selenium.webdriver.support import expected_conditions as EC 3from selenium.webdriver.common.by import By 4try: 5 sleep(8) 6 ps = driver.find_elements(By.TAG_NAME, "p") 7 print(location(), len(ps)) 8except Exceptino as e: 9 print(e)

zsh

1len(ps)の結果が13~17の間でランダムに取得されます

改善コード

Python

1from selenium.webdriver.support.ui import WebDriverWait 2from selenium.webdriver.support import expected_conditions as EC 3from selenium.webdriver.common.by import By 4try: 5 wait.until(EC.visibility_of_all_elements_located((By.TAG_NAME, "p"))) 6 ps = driver.find_elements(By.TAG_NAME, "p") 7 print(location(), len(ps)) 8except Exceptino as e: 9 print(e)

Zsh

1Message: 2

バージョン情報
Python 3.10.8
selenium 4.9.0
firefox 92.0.1 (64 ビット)

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

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

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

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

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

poto568

2023/05/22 02:55

「selenium visibility_of_all_elements_located」でggると 以下の記事がトップに来ていました。 https://1024.hateblo.jp/entry/2022/01/15/011604 検証や公式の確認を行って、わかったことがあれば質問に追記 していただけると識者がアドバイスをくれるかもしれません。
fuku-chann

2023/05/22 03:50

ありがとうございます。 上記検討させていただきますが、スクレイピングする際にget.driver(url)後、はじめに要素を取得する時は通常どうされているのでしょうか?
guest

回答1

0

ベストアンサー

スクレイピングする際にget.driver(url)後、はじめに要素を取得する時は通常どうされているのでしょうか?

JavaScriptで要素が追加されたり書き直されたりした場合に、それが全件終わるまで待たないといけないケースの話ですよね?
以下はその前提で書いています。

wait.until(EC.visibility_of_all_elements_located((By.TAG_NAME, "p")))

で、「今後 p タグがどんどん追加されるけど、追加が終わったら教えて」ということを指示したつもりですかね?
「何を以て終わったと判断するか」を指示に含めることなくそんな指示が実行出来るはずがありません。

スクレイピングする際にget.driver(url)後、はじめに要素を取得する時は通常どうされているのでしょうか?

何処まで待つのかをよく考えて、それまで待ちます。

やり方例としては、待ちきれずにfind_elementsを実行してしまったことがわかった場合、
その直前にdriver.page_sourceをファイルに書く行を挿入します。
その状態で、「待ちきれずに実行した」が再現したら、そのファイルに書かれたHTMLと、
手動でブラウザで見て「このHTMLになるまで待ちたいんだよね」という状態のHTMLとを見比べて、よく考えます。

何を待つと良いのかは、ページによって異なるので、ページ毎によく考えるしかないです。
よく考えても無理というケースもあり得ますね。
例えば、<ul></ul>の間に<li>が追加されていくとして、「全部で何個か」がどこかに表示されているケースではその数字の個数になるまで待てば良いですね。
全体の個数が不明で、その時点で末尾の<li>が最後のものかどうかを判断する手段もない場合等は、時間を「さすがにこれだけ待てば大丈夫だろ」というだけ待つ以外に無いでしょうね。最初から最後までの時間のリミットを決めるのでなく、細かく「直近の追加から○秒経ってさらに追加がない場合は終わりと判断」とかもありかと。
もしくはSeleniumが開くブラウザ画面を見ている人がいるような実行方法なら、input("ブラウザ画面を見て情報がそろったらEnterを押して下さい")を入れて、人間が判断するか。

別件ですが、

エラーメッセージが空白のため原因が特定に苦戦しています。

エラーメッセージを知りたいにもかかわらず、try exceptを書いているのが間違っています。
何を目的としてtry exceptを書いたのでしょうか?
try exceptは、どんな例外が発生するかを把握していて、その例外に対しての対処を決めている場合に使います。

Python

1try: 2 例外が起こるかも知れない文 3except 起こるかもと思っている例外名その1 as e: 4 例外名その1が発生したときの対処 5except 起こるかもと思っている例外名その2 as e: 6 例外名その2が発生したときの対処

投稿2023/05/23 15:58

otn

総合スコア84555

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

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

fuku-chann

2023/05/24 21:22

普段感じていたもやもやが払拭されました。 ありがとうございます。 try: exceptの件ですが、except Exception as e: print(e)としてエラー内容を表示させ、デバック時に役立てることを目的としています。
otn

2023/05/25 04:04

> エラー内容を表示させ、デバック時に役立てることを目的としています。 try や except を書かなければ、詳細なエラーメッセージやトレースバック情報が表示されますが、 自分で例外を捕捉してしまうと、同様以上の情報を表示するのは不可能では無いものの、無意味な手間です。 print(e)のように情報表示に手を抜くと今回のように情報不明となります。 try や except を書くのは、メインロジックのデバッグが全部終わって、想定内の例外にどう対処するかが決まった場合です。
fuku-chann

2023/05/26 02:09

crontabを使って定期的に複数のコードを実行しています。 たまにしか出ないエラーを残して、try exceptを使用している状況です。 try exceptを使用している理由は、たまにしか出ないエラーが出た場合でも、driverをquitさせたいからです。 たまにしか出ないエラーより毎回実行させることを優先しています。
otn

2023/05/26 06:03

13:04のコメントは、 > try: exceptの件ですが、except Exception as e: print(e)としてエラー内容を表示させ、デバック時に役立てることを目的としています。 に対してのものなので、上記が違うのなら、関係ないです。 > try exceptを使用している理由は、たまにしか出ないエラーが出た場合でも、driverをquitさせたいからです。 「driverをquitさせたくない」の間違いですかね? 障害原因分析より継続を優先するという決めであれば、それで問題ないと思います。
fuku-chann

2023/05/26 10:45

説明不足ですみません。 途中でエラーがでるとdriver.quit()まで辿り着かず、ドライバが終了しないことがあります。この状態になると次回以降、同じドライバーを複数立ち上げられないのでエラーになってしまい、手動でこのブラウザを終了するまでcronが実行されません。頻度の低いエラーによってこの状態になることを回避するためにtry exceptを使用していることが一番の目的になります。
otn

2023/05/26 11:01

あ、確かに、ブラウザが終了しないことありますね。誤読、失礼しました。 そこが目的なら、 except Exceptino as e: driver.quit() raise でおそらく、 driver.quit() した後で標準の詳細なエラーメッセージが出るかと思います。試してませんが。 やりたいことがストレートに書いてあればコメントの往復が減らせます。
fuku-chann

2023/05/29 04:07

raise試してみます。 ありがとうございました。 >やりたいことがストレートに書いてあればコメントの往復が減らせます。 承知いたしました。 続きでご質問があります。これから新規で質問しますので、よろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問