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

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

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

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

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

selenium

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

Q&A

解決済

2回答

1818閲覧

python seleniumでタグ名に「button」が含まれる要素を取得し、取得した要素のタグ名をすべて取得したい

fuku-chann

総合スコア82

Python 3.x

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

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

selenium

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

0グッド

0クリップ

投稿2023/04/23 10:54

編集2023/04/23 20:54

タグ名に「button」が含まれる要素を取得し、すべてのタグ名を取得するコードを作成していますが、うまく取得できないのでご質問させていただきます。
ChatGPTに下記の2パターンのコードを作成してもらいましたが、どちらも1つも取得できませんでした。(len(buttons)が0で出力されます)
どこが違っているかご存知の方おられましたら、ご教示お願いします。

パターン1

Python

1buttons = driver.find_elements(By.XPATH, "//button[contains(name(), 'button')]")

パターン2

Python

1buttons = driver.find_elements(By.XPATH, "//button[contains(@tag, 'button')]")

Python

1driver.get(url) 2sleep(5) 3print(location()) 4# tag名に"button"が含まれる要素をすべて取得する 5# buttons = driver.find_elements(By.XPATH, "//button[contains(@tag, 'button')]") 6buttons = driver.find_elements(By.XPATH, "//button[contains(name(), 'button')]") 7print(location(), len(buttons)) 8 9# 取得した要素を表示する 10for button in buttons: 11 print(location(), button.tag_name)

以下ChatGPTの回答です。
直接要素を取得することはできるので2と3ではないと考えています。

要素が取得できない場合、要因としてはいくつか考えられます。

  1. Xpath式が正しくない
  2. 要素がまだ読み込まれていない
  3. 要素が存在しない

以下の手順でトラブルシューティングをお試しください。

Xpath式が正しいことを確認してください。適切な要素を取得できるようになっているかどうかを確認するために、ブラウザの開発者ツールなどを使用してXpath式をテストすることができます。
ウェブサイトが遅い場合、要素が読み込まれるまで時間がかかる場合があります。適切なウェイトを追加して、ページが完全に読み込まれるまで待ってから要素を取得することができます。例えば、time.sleep()を使用するか、WebDriverWaitクラスを使用して、要素が表示されるまで待つことができます。
要素が存在しない場合、取得することができません。別のXpath式を使用するか、要素が存在することを確認してから再度試してください。

Python

1buttons = driver.find_elements(By.TAG_NAME, "button") 2print(len(buttons))

結果が6になりますので、6以上取得できないのは、コード側の問題と推測しています。

driver.get以降のコードをコピペします。

Python

1driver.get(url) 2sleep(10) 3buttons = driver.find_elements(By.TAG_NAME, "button") 4print(location(), len(buttons)) 5buttons = driver.find_elements(By.XPATH,"//*[contains(name(), 'button')]") 6print(location(), len(buttons))

結果はこちらになります

zsh

1('/Users/test3.py', '<module>', 186) 6 2('/Users/test3.py', '<module>', 188) 0

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

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

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

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

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

meg_

2023/04/23 11:08

> タグ名に「button」が含まれる要素を取得し 例えばどのような要素でしょうか?簡単なサンプルhtmlを提示できますでしょうか?
fuku-chann

2023/04/23 11:12

タグ名が「icon-button」などが該当します。htmlの提示は控えさせていただきます。(すみません::)
melian

2023/04/23 11:56

動作確認ができないので確証はありませんが、以下の様にするとよいかもしれません。 buttons = driver.find_elements(By.XPATH, "//*[contains(name(), 'button')]")
fuku-chann

2023/04/23 13:01

ご回答ありがとうございます。 試してみましたが、取得できませんでした。(len(buttons)が0になりました)
guest

回答2

0

回答ではなく確認ですが、以下の buttons.html をソースコード(test3.py)と同じディレクトリに置いて、

buttons.html

html

1<div class="test"> 2 <button id="button1"></button> 3 <icon-button id="button2"></icon-button> 4 <1button id="button3"></1button> 5 < button-ok id="button-ok"></button-ok> 6</div>

以下の様に書き換えて実行してみてください。手元の環境(Python 3.11.2/Selenium 4.9.0/ChromeDriver 112.0.5615.28)では buttonicon-button が表示されます。

test3.py

python

1import os 2 3# 4# 初期化コード 5# 6 7url = f'file://{os.path.dirname(__file__)}/buttons.html' 8driver.get(url) 9 10buttons = driver.find_elements(By.XPATH, "//*[contains(name(), 'button')]") 11for button in buttons: 12 print(button.tag_name)

投稿2023/04/24 06:45

melian

総合スコア19791

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

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

fuku-chann

2023/04/24 07:13

確認のご提案ありがとうございます。 下記の結果が出力されました。(melianさんの結果と異なるようです。) <1button id="button3"> < button-ok id="button-ok">
melian

2023/04/24 07:21

なるほど、そちらの Selenium のバージョンはどうなっていますでしょうか? 確認方法は、python を起動して(インタラクティブモード)、以下を入力してください。 import selenium print(selenium.__version__)
fuku-chann

2023/04/24 08:36 編集

下記の結果になりました。 4.7.2 調べたら一年前のバージョンのようですが、バージョンが影響している可能性ありますでしょうか? よろしければ、参考までにご利用のバージョンご教示いただけますでしょうか?
melian

2023/04/24 08:47

4.x 系であれば問題はないかと思うのですが、こちらで利用しているのは 4.9.0 です。
fuku-chann

2023/04/24 09:19

ありがとうございます。 すみません、バージョンアップの手順は下記で問題ないでしょうか? pip install selenium==4.9.0 3日前にリリースしたみたいで、firefoxとの連携がうまくいくか情報ないみたいですが、試してみないとわからないですよね?
melian

2023/04/24 09:44

はい、問題ありません。もしも支障があれば、pip install selenium==4.7.2 として元に戻すとよいかと思います。
fuku-chann

2023/04/24 09:51

4.9.0になりましたが、同じ結果になりました。 <1button id="button3"> < button-ok id="button-ok">
melian

2023/04/24 10:03

そうなりますと、違いはブラウザということになりそうです。私の方では Chrome を使っていますが、後ほど Firefox でも試してみます。
fuku-chann

2023/04/24 10:24

お手数おかけいたしますが、よろしくお願いします。
melian

2023/04/24 12:12

Firefox で試した所、再現しました。Firefox では name() ではなく local-name() を使うとマッチする様です。 buttons = driver.find_elements(By.XPATH, "//*[contains(local-name(), 'button')]")
fuku-chann

2023/04/24 12:23 編集

素晴らしい。ビンゴです。 buttons = driver.find_elements(By.XPATH, "//*[contains(local-name(), 'button')]") print(len(buttons)) -> 16になりました。 どうやってlocal-name()だとわかったのでしょうか? 解決までの手順をご教示ください。
melian

2023/04/24 12:34

contains と name() の組み合わせが原因かな、と思って「selenium xpath "//*[contains(name()"」で検索していたら、以下の記事がヒットしたのです。回答で local-name() が使われていたので試してみた所、上手く行った次第です。ただ、なぜ Firefox では name() が使えないのかは判りませんね。。。 Find XPath attribute name contains specific string https://stackoverflow.com/questions/47650002
fuku-chann

2023/04/24 12:39

やはり検索力ですね。 とても勉強になりました。 ありがとうございました。
fuku-chann

2023/04/24 12:42 編集

サクッとfirefoxとchromeを両方試せる環境があることも素晴らしいです。 私もテストファイルに両方試せるよう準備したいと思います。
guest

0

ベストアンサー

"//button[contains(name(), 'button')]"

「要素名がbuttonである物のうち、要素名の一部にbuttonが含まれる要素」なので、「要素名がbuttonである要素」と全く同じ意味になります。"//button"ですね。

"//button[contains(@tag, 'button')]"

「要素名がbuttonである物のうち、tag属性の値の一部にbuttonが含まれる要素」なので、
<button tag="x-button">のような要素が該当します。
⇒ ChatGPTの回答は結構間違っているので、合っているか間違っているか判断する能力が必要です。

タグ名に「button」が含まれる要素を取得し

の日本語文章をそのままXPathにすると、//*[contains(name(), 'button')]ですが、見つからないとすると、
実際のHTMLが想定しているHTMLと異なるのでしょう。

Python

1driver.get(url) 2sleep(5) 3print(driver.page_source)

して、HTMLを確認しましょう。

投稿2023/04/23 13:50

otn

総合スコア84553

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

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

fuku-chann

2023/04/23 14:14 編集

ご回答ありがとうございます。説明文に追記しましたが、buttons = driver.find_elements(By.TAG_NAME, "button")で6個要素が取得されます。buttonを含むコードの場合、6個以上にならないとおかしいです。
otn

2023/04/23 14:48 編集

なるほど。 buttons = driver.find_elements(By.TAG_NAME, "button") print(len(buttons)) buttons = driver.find_elements(By.XPATH, "//*[contains(name(), 'button')]") print(len(buttons)) を同じプログラムの中で連続して実行して、6 と 0 が表示されるという事で間違いないですか? あと、問題点と関係しない気はしますが、コード中の location() というのは何者でしょうか?
fuku-chann

2023/04/23 14:53

お間違いないです。 location()はprintした行が出力される関数です。
otn

2023/04/23 15:30

> お間違いないです。 その実行したプログラムを、少なくともdriver.get(~)以降、最後のprint(len(buttons))までの部分を、改変せず質問にコピペ追記してください。
fuku-chann

2023/04/23 20:55

追記いたしました。 ご確認お願いいたします。
otn

2023/04/24 06:09

タイプミスなどを疑ったのですが、大丈夫そうですね。 print(By.XPATH) の結果は 'xpath' でしょうか? print(len(driver.find_elements(By.XPATH,"//button"))) print(len(driver.find_elements(By.CSS_SELECTOR,"button"))) とかはどうでしょうか?
fuku-chann

2023/04/24 09:21

両方7になります。 print(len(driver.find_elements(By.XPATH,"//button"))) print(len(driver.find_elements(By.CSS_SELECTOR,"button")))
otn

2023/04/24 12:04

6でないのが不思議です。 driver.find_elements(By.TAG_NAME, "button")が6件だったのと違うHTMLなのでしょうね。
otn

2023/04/24 12:10

他のコメントを見ると、ChromeじゃなくてFirefoxなのでしょうか? FirefoxでXPathの動作をみると、どうも、Firefoxのname()関数は英大文字を返すようです。 Selenium+ブラウザの内部の処理方式を知りませんが、ブラウザ側にXPath処理を任せるという方式なのなら、大文字でいけるかも知れません。 driver.find_elements(By.XPATH, "//*[contains(name(), 'BUTTON')]") でどうでしょうか?
otn

2023/04/24 12:15

<Firefox> document.evaluate('name(//div)', document, null, XPathResult.ANY_TYPE, null) => XPathResult { resultType: 2, stringValue: "DIV", invalidIteratorState: false } <Chrome> document.evaluate('name(//div)', document, null, XPathResult.ANY_TYPE, null) => XPathResult {resultType: 2, stringValue: 'div', invalidIteratorState: false}
fuku-chann

2023/04/24 12:19

ありがとうございます。 あっしゃる通りでした。 大文字で16になりました。連続で小文字が0になりましたので間違いないです。 buttons = driver.find_elements(By.XPATH, "//*[contains(name(), 'BUTTON')]") -> len(buttons) = 16 buttons = driver.find_elements(By.XPATH, "//*[contains(name(), 'button')]") -> len(buttons) = 0 下記は具体的にどこをみられたのでしょうか? >FirefoxでXPathの動作をみると
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問