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

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

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

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

Q&A

解決済

1回答

543閲覧

seleniumで要素の制御が正しくできているかをデバッグの一助として知る方法

sigefuji

総合スコア125

selenium

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

0グッド

0クリップ

投稿2023/04/02 07:34

編集2023/04/02 07:43

実現したいこと

・find_elementが意図通りできない
・例えば、 driver.find_element(By.SPAN CLASS).text()
のようなことに相当する記述

前提

添付画像の1.Histrical data のクリックによって、設定パネルが開いたり、閉じたりします。
現在 Histrical dataなるパネル1が開かれているか、閉じているかを判定したい。

HTMLの変化を調べると、違いはこの範囲では次の通りです。
閉じているとき
<span class="glyphicon pull-right glyphicon-chevron-down" aria-hidden="true"></span>

<div class="panel-collapse collapse" id="collapse>

開いているとき
<span class="glyphicon pull-right glyphicon-chevron-up" aria-hidden="true"></span>

<div class="panel-collapse collapse in" id="collapse1"> ::before (追加される)

方法として,xpathで直前に移動した後,それぞれに特有の要素があるかを調べることにしました。

開示のコードを実行しても、faultでいずれも認識されないことになります。

正しい記述を教わってもありがたいですが、
このようなケースの場合、意図した要素をきちんと的を射ているかが疑問なります。
つまり、注目した<span class="*****">の***の部分をどのようにseleniumが認識しているかを知ることができれば、
原因を知ることに大いに助けになると思うのです。このままでは、推測するだけでいつまでたっても似たような問題で困ることになります。

例えば、 driver.find_element(By.SPAN CLASS).text()
のようなことに相当する記述はないでしょうか。
は<span class="*****" とあるとき、*****を取得することです。

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

意図した要素を制御できない

エラーメッセージなし

該当のソースコード

python

1import time 2#selenium ver 4.8.2 3from selenium import webdriver 4from selenium.webdriver.common.by import By 5from selenium.webdriver.support.ui import WebDriverWait 6from selenium.webdriver.support import expected_conditions as EC 7from selenium.common.exceptions import TimeoutException 8from selenium.webdriver.support.select import Select 9 10driver = webdriver.Chrome("c:/driver/chromedriver.exe") 11driver.get("https://eas.forexsb.com") 12wait = WebDriverWait(driver, 10) 13 14element = wait.until(EC.element_to_be_clickable((By.ID, 'user-sign-in-email'))) 15EC.element_to_be_clickable((By.ID, 'user-sign-in-email')) 16email = driver.find_element(By.ID,"user-sign-in-email") 17email.send_keys("y.f-oka@outlook.jp") 18elem_login_pw = driver.find_element(By.ID,"user-sign-in-password").send_keys("qACSqwvD") 19elem_login_email = driver.find_element(By.ID,"user-sign-in-submit").send_keys("keys.ENTER") 20 21 22elm_confirm=wait.until(EC.element_to_be_clickable((By.ID,'eas-main-accept-legal'))) 23elm_confirm.click() 24#element.send_keys("keys.ENTER") 25 26print("confirm ok") 27time.sleep(2) 28 29elm_generator=driver.find_element(By.ID,"acquisition-link"); 30elm_generator.click() 31 32print("generator") 33 34time.sleep(5) 35 36 37 38xpath = "//div/div/h4/a" 39driver.find_element(by=By.XPATH,value=xpath) 40 41try: 42 elm_updown = driver.find_element(By.CLASS_NAME,"glyphicon pull-right glyphicon-chevron-up") 43 print("up") 44 up=1 45except: 46 up=0 47 48try: 49 elm_updown = driver.find_element(By.CLASS_NAME,"glyphicon pull-right glyphicon-chevron-down") 50 print("down") 51 down=1 52except: 53 down=0 54 55if up==1 and down==0: 56 print("safe up") 57elif up==0 and down==1: 58 print("safe down") 59else: 60 print("fault") 61 62 63

試したこと

ここに問題に対して試したことを記載してください。

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

1.Histrical dataに関する設定パネルが閉じているとき <div class="panel-group" id="settings-container"> <h4>Generate new strategies</h4> <div class="panel panel-default"> <div class="panel-heading"> <h4 class="panel-title"> <a data-toggle="collapse" data-parent="#settings-container" href="#collapse1">1. Historical data</a> <span class="glyphicon pull-right glyphicon-chevron-down" aria-hidden="true"></span> </h4> </div> <div class="panel-collapse collapse" id="collapse1"> <div class="panel-body"> <form class="form-horizontal form-no-submit" autocomplete="off" style="margin-bottom: 30px;"> <div class="form-group"> <form class="form-horizomtal form-no-submit" autocomplete="off" style="margin-bottom;30px;"> 1.Histrical dataに関する設定パネルが開かれているとき <div class="panel-group" id="settings-container"> <h4>Generate new strategies</h4> <div class="panel panel-default"> <div class="panel-heading"> <h4 class="panel-title"> <a data-toggle="collapse" data-parent="#settings-container" href="#collapse1">1. Historical data</a> <span class="glyphicon pull-right glyphicon-chevron-up" aria-hidden="true"></span> </h4> </div> <div class="panel-collapse collapse in" id="collapse1"> <div class="panel-body"> <form class="form-horizontal form-no-submit" autocomplete="off" style="margin-bottom: 30px;"> <div class="form-group"> ::before <form class="form-horizomtal form-no-submit" autocomplete="off" style="margin-bottom;30px;">

対象サイト
https://expert-advisor-studio.com/
trialであれば、自由に使えます。

python 3.8.11
selenium 4.11
chrome使用

パネル1、パネル2、パネル3のスクリーンショット

イメージ説明

パネル1を開いた画面
イメージ説明

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

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

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

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

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

hawawa

2023/04/02 08:58

グーグルなどの検索サイトで Python selenium 属性値 html 属性とは とかのキーワードで調べてみるとよいのでは
guest

回答1

0

ベストアンサー

<span class="*****" とあるとき、*****を取得することです。

driver.find_element(該当spanタグを一意に特定する指定).get_attribute("class")
です。
まずは、「Selenium入門」的な物を読んで、基本を学ぶのが良いと思います。

一意に指定する事が困難な場合は、全部取得して、選択する方法もあります。

Python

1for span in driver.find_elements(By.TAG_NAME,"span"): 2 if 何らかの条件: 3 条件を満たしたspanタグに対する処理

39行目のdriver.find_element(by=By.XPATH,value=xpath)はメソッドの返り値を捨てているので書いても無意味ですね。

投稿2023/04/02 10:34

otn

総合スコア84529

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

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

sigefuji

2023/04/02 11:47

ご返事ありがとうございます。 主題は<span class="*****" とあるとき、*****を取得することですなのですが、 driver.find_element.get_attribute("class")     #一個だけ指定 これから****をどのように取得できますか? except: text=driver.find_element.get_attribute("class"),text() ??? print(text) では AttributeError: 'function' object has no attribute 'get_attribute' となります text=driver.find_element.get_attribute("class") ??? でもエラーです。 このclass名をtextで取得したいのです。確認のためです。
otn

2023/04/02 12:11

回答のコードを > driver.find_element(該当spanタグを一意に特定する指定).get_attribute("class") と書いたのに何故それを無視して、変なコードを書くのでしょうか?? find_elementの意味がわかっていないのでしょうか? まずは、「Selenium入門」的な物を読んで、基本を学ぶのが良いと思います。
sigefuji

2023/04/02 12:17

わかりませんでしたので、変なコードなのでしょう。自分なりに勝手に考えました。 dfriver.find_element.get_attribute("class") ここから、****をどのように取得すればよいのでしょうか?
otn

2023/04/02 12:30

driver.find_element(該当spanタグを一意に特定する指定).get_attribute("class") というコードの意味がわからないと言うことなのでしょうか? 何がわかって何がわかりませんか?
sigefuji

2023/04/02 12:44

これは正しいですか。 elm_updown = driver.find_element(By.CLASS_NAME,"glyphicon pull-right glyphicon-chevron-up") text =elm_updown.get_attribute("class") # <span class="glyph..... print("up", text) もしglyph....がhtmlに確かにあれば、printでそれが出力されるが、もしなければ、2番目の行でエラーになりますね。 その状態のとき、<span class="glyph.....のhtmlをseleniumがどのように読んだかの疑問です。 ーーーーー driver.find_element(該当spanタグを一意に特定する指定).get_attribute("class") これはよいですが、これをどのようにつかうかとの「疑問でしたが 上記のように driver.find_element.get_attribute("class")
sigefuji

2023/04/02 12:45

上の投稿はミスしました。捨ててください
sigefuji

2023/04/02 12:59

htmlコード <span class="glyphicon pull-right glyphicon-chevron-up" aria-hidden="true"></span> にたいして、 elm_updown = driver.find_element(By.CLASS_NAME,"glyphicon pull-right glyphicon-chevron-up") を実行しますが、エラーになります。 この状態で、"glyphicon pull-right glyphicon-chevron-up"なる文字列を取得したいのが目的です。 教わった driver.find_element.get_attribute("class") を使ってどのように具体的にコードすればよいかが、わからない点です。
sigefuji

2023/04/02 13:02

はなはだ勝手で申し訳ありませんが」、ご返事は明日にさせていただきます。」
otn

2023/04/02 15:25

> 教わった > driver.find_element.get_attribute("class") > を使ってどのように具体的にコードすればよいかが、わからない点です。 そんなコードは書いてませんが。 driver.find_element(該当spanタグを一意に特定する指定).get_attribute("class") と、 driver.find_element.get_attribute("class") が、同じに見えるのであれば、「Selenium入門」の前に「Python入門」を読んで、関数やメソッドとは何かについて学びましょう。 find_elementはメソッドなので、引数を付けて呼び出します。 driver.find_element(By.ID,"user-sign-in-email") driver.find_elements(By.TAG_NAME,"span") とかですね。 driver.find_element(該当spanタグを一意に特定する指定).get_attribute("class") は、その引数を日本語で書いただけです。 目的の要素に対して、どのように指定すれば、全体の中で一意に特定できるかは、全体のHTMLを見て考えます。多くの場合は、試行錯誤します。 そのためには、XPathの知識またはCSSセレクタの知識の少なくとも一方が必要です。 それに加えてSeleniumの基本知識も必要ですし、それ以前に driver.find_element.get_attribute("class") のようなコードを書かないレベルのPythonに関する基本知識も必要です。
sigefuji

2023/04/03 08:34

<span class="glyphicon pull-right glyphicon-chevron-up" aria-hidden="true"></span> にたいして、 elm_updown = driver.find_element(By.CLASS_NAME,"glyphicon pull-right glyphicon-chevron-up") を実行しますが、エラーになります。 この状態で、"glyphicon pull-right glyphicon-chevron-up"なる文字列を取得したいのが目的です。 とお尋ねしました。 これは、 elm_updown = driver.find_element(By.CLASS_NAME,"glyphicon pull-right glyphicon-chevron-up") text=elm_updown.get_attribute("class") print("text",text) または、 elm_updown = driver.find_element(By.CLASS_NAME,"glyphicon pull-right glyphicon-chevron-up").get_attribute("class") print("text",text) と記述すればよいわけですね。このようなご返事を期待していました。 OTN様のご返事は、必要十分なことと、今になれば理解いたしますが、その時はわかりませんでした。 いわば、百聞は一見に如かずのような感じですね。 こうであれば一件落着としたいところですが、なぜか上記の場合は解決しませんです。 上記までのいくつかのステップでうまく行ったのは、次の通りです。 elm_generator_navbar=driver.find_element(By.ID,"generator-navbar") text=elm_generator_navbar.get_attribute("class") print("nabvar-text", text) elm_generator_container=driver.find_element(By.ID,"generator-container") text=elm_generator_container.get_attribute("class") print("generator-container text", text) text=driver.find_element(By.ID,"settings-container").get_attribute("class") print("settings-container2 text", text) elm_settings_container=driver.find_element(By.ID,"settings-container") text=elm_settings_container.get_attribute("class") print("settings-container text", text) ところが、 <span class="glyphicon pull-right glyphicon-chevron-up" aria-hidden="true"></span> について、 elm_updown = driver.find_element(By.CLASS_NAME,"glyphicon pull-right glyphicon-chevron-up") text=elm_updown.get_attribute("class") print("text",text) としても、 no such element: Unable to locate element: となります。 うまく行ったのと比べると、<span class=が違います。 しかし、そのようなことはいかにもありそうになく、恐らく、タイプミスと思いたいわけです。 それで、そのような場合でも、どんな風にseleniumには見えるのかを知りたいのが、この質問の当初の趣旨でした。やはり、elementsですべて拾い出して調べるほかないでしょうか。
otn

2023/04/03 09:36

> driver.find_element(By.CLASS_NAME,"glyphicon pull-right glyphicon-chevron-up") 過去にちゃんと書いているので、そのうち自分で気づくと思っていたのですが、 driver.find_element(By.CLASS_NAME,"glyphicon.pull-right.glyphicon-chevron-up") ですね。以前出来てたことが何故出来なくなっているのか不思議です。 > 今になれば理解いたしますが、その時はわかりませんでした。 「該当spanタグを一意に特定する指定」という言葉の意味が通じないとは思ってなかったのですが、意味がわからないのなら、「意味がわからない」と書いて貰えば説明できました。 classを全部指定したのなら、取得したタグのclass属性を参照する必要は無いわけで、 取得したタグのclass属性を参照する必要があるとすれば、 「classを全部指定する」以外の方法でタグを特定したいのだろうなと思って日本語で書きました。 その想定が間違っていたのでしょうか? classを全部指定してタグを取得してそのclass属性を取得しても、タグ特定の時に指定した物が得られるだけなので、無意味ですよね? 再度書きますが、基本を理解していない状態で試行錯誤するのは時間の無駄だと覆います。 Pythonプログラムを書くのが今回限りなら、それでもいいのかもしれませんが。
sigefuji

2023/04/03 12:07

>ですね。以前出来てたことが何故出来なくなっているのか不思議です。 恐らく貴殿が再三ご指摘のように、正確に理解していなかったからでしょう。 ですから、再三具体的コードをお尋ねしたのです。ご推測いただければ幸いです。 後半の新たな疑問はなにか気が付かれたことはありませんか。
otn

2023/04/03 13:12

> 後半の新たな疑問はなにか気が付かれたことはありませんか。 後半の新たな疑問とは何のことでしょうか?
otn

2023/04/03 13:16

> その想定が間違っていたのでしょうか? はどうなのでしょうか?
sigefuji

2023/04/03 22:40

小生の 2023/04/03 17:34 投稿 こうであれば一件落着としたいところですが、なぜか上記の場合は解決しませんです。 ・・・・・・・ ところが、 <span class="glyphicon pull-right glyphicon-chevron-up" aria-hidden="true"></span> について、 elm_updown = driver.find_element(By.CLASS_NAME,"glyphicon pull-right glyphicon-chevron-up") text=elm_updown.get_attribute("class") print("text",text) としても、 no such element: Unable to locate element: となります。 うまく行ったのと比べると、<span class=が違います。 しかし、そのようなことはいかにもありそうになく、恐らく、タイプミスと思いたいわけです。 それで、そのような場合でも、どんな風にseleniumには見えるのかを知りたいのが、この質問の当初の趣旨でした。やはり、elementsですべて拾い出して調べるほかないでしょうか。
otn

2023/04/04 00:03

no such element: Unable to locate element: となるのは、クラス名指定が間違っているからです。 2023/04/03 18:36 のコメントに正しい指定を書いたのですが、見落としでしょうか? > そのような場合でも、どんな風にseleniumには見えるのかを知りたいのが、 「そのような場合」というのは、find_element の引数の指定を間違った場合でしょうか? 間違った指定をしても、Seleniumはその指定の通りに動作します。 セレクターとして文法的に正しければ、指定通りのタグを検索して、見つからないもしくは想定外のタグを見つける。 セレクターとして文法的に間違っていれば、そういうエラーになるでしょう。
sigefuji

2023/04/04 03:17

あ、これですか glyphicon.pull-right.glyphicon-chevron-up スペース区切りが、ドット区切りになっている。 先に、どこか他を見てこのことも経験していたので、多少気になっていました。 一度は、クラス名のスペースはドットにすべきなのかなと思ったりしたのですが、スペースで良い場合もあったので、そうではないだろうと思いなおしていたのです。 本当にスペース区切りはドット区切りに置き換えるが正しいですか。 裏付けるサイトはありませんか。
otn

2023/04/04 04:07 編集

> 先に、どこか他を見てこのことも経験していたので、多少気になっていました。 前の質問だと自分でちゃんとピリオドで書いてたのですが、忘れてしまったのですかね。 By.CSS_SELECTORの場合は、そのままCSSセレクターの指定を書くので、 .glyphicon.pull-right.glyphicon-chevron-up ですが、By.CLASS_NAMEだと、CSSセレクターの先頭のピリオドだけ落とすようです。 ただ、公式サイト https://www.selenium.dev/ja/documentation/webdriver/elements/locators/ には、 > class name class名に値を含む要素を探す (複合クラス名は使えない) と書いてあるので、複合クラス名に対して By.CLASS_NAME を使うのは間違っていて、 上記のBy.CSS_SELECTORを使うのが正しいようです。
sigefuji

2023/04/04 07:54

やはり、ドットのありなしがあったのですね。私がなぜドットを付けたかは、どこかで見たのだと思いますが忘れました。なぜだろうとは思っていました。つまるところ、これで随分と苦しんだのです。原因の入り口に来たようです。 ご案内のサイト、見ましたが、ドットのことについての記述はわかりません。ぜひ教えてください。
otn

2023/04/04 09:53

> ご案内のサイト、見ましたが、ドットのことについての記述はわかりません。ぜひ教えてください。 class="aaa bbb ccc ddd" のようにタグのクラス名のところに空白区切りで複数書いてある物を、「複合クラス名」と言います。そのページで見て欲しかったのは、下記の部分です。 > class name class名に値を含む要素を探す (複合クラス名は使えない) CSSセレクターの書き方は、「CSSセレクター」で検索するといろいろなサイトで説明されています。
sigefuji

2023/04/04 12:25

複合クラスと言うものだったのですか。class_nameで使うのは間違っていて、CLASS_SELCTORを使うべしなことわかりました。CLASS_SDELCTORはもう少ししらべますが、とりあえず、空白をドットにするとなぜかヒットしました。後続の_upはヒットしなかったので、理屈はあっていそうです。 実は、このサイトはtrial版でして、今晩で期限切れです。とりあえず、先に進めることがわかりましたので、機会を作って再挑戦します(別のメールアドレスを用意しなければならない)。 回り道でしたがいろいろありがとうございました。
otn

2023/04/04 13:43

> 回り道でしたがいろいろありがとうございました。 王道を進んでないと、いろいろ回り道をすることになります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問