1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Seleniumで要素が取得できない!

Posted at

※この記事は新入社員の問いにあることないことないことないこと話した備忘録です。

本日の困りごと

Seleniumを使ってのWebサイトやWebシステムの自動検証。

find_element_by_xpathを使ってもこの要素取れないんです!
この直前の要素なら取れるのに…!

経緯

元々「このサイトは何故かSeleniumで検証できないんですよねー」と言われているWebサイトがあった。

えぇwまさかぁwww
作った人(もういない)の組み方が悪いんだってwww

と、メンバーに「組みなおしてみ?」と依頼する。
すると返ってきたのがこの言葉。

なるほど。丸投げしてたのでHTMLでも見てみようじゃないか。

今回の解決方法

みんな、HTMLにはclass属性やid属性を付けようぜ!

…とはいえ「検証の自動化」を行うために画面を修正するのはナンセンスである。
WebサイトWebサイトと言っているが、どうせ中身はWebシステム。phpだったりJSPだったりするものだろう。

今回はsample.htmlから、記事2の本文を取得したい!
…という要件だったとして解説をしたいと思う。

sample.html
<html>
    <head><!-- 省略 --></head>
    <body>
        <div id='wrap'>
            <div class='article'>
                <article>
                    <h1>記事1のタイトル</h1>
                    <div>
                        <p>記事1の本文</p>
                    </div>
                </article>
            </div><!-- .article -->
            <div class='article'>
                <article>
                    <h1>記事2のタイトル</h1>
                    <div>
                        <p>記事2の本文</p>
                    </div>
                </article>
            </div><!-- .article -->
        </div><!-- #wrap -->
    </body>
</html>

「動かない」といわれた指定方法がこちら。

動かない.py
path = "/html/body/div/div[2]/article/div"
elmt = driver.find_element_by_xpath(path)

htmlの中のbodyの中のdiv(id=wrap)の中のdiv(class=article)の2つ目のarticleの中のdivを指定したいらしい。

ふむふむ。それって"/html/body/div[5]"なんじゃね?

動くと思う.py
path = "/html/body/div[5]"
elmt = driver.find_element_by_xpath(path)

xpathの指定では、画面の要素がどのようにネストしているかは関係ない
**「上から何回目に登場したdivか?」**が判定の基準となる。
CSSの疑似クラス:nth-child()に似ているだろうか。

2つ目の<div class='article'>を非表示にしたくて

色々消えちゃう.css
div#wrap div:nth-child(2) { display: none; }

と指定すると、1つ目のdiv#wrapの中の「2つ目のdiv」を軒並み消してしまう。
sample.htmlの場合は記事1の本文と記事2が全て非表示となる。
(サンプルなのでclass指定しろよ!…とは言ってはいけない)

うーん。なんか例が悪いな。。

結論

なんせプログラマという生き物はインデントとかネストとかを気にして生きている人種なので勘違いしてしまうこともあるのだが、外部のプログラムにそのHTMLがどんな構成で書かれているかはわからない。
CSSだろうがPythonだろうがJavaだろうが、彼らは人の意思を酌んで動いてくれるものではないのだ。
今回の場合のように「記事が複数あるから同じようなブロックがある」を知っているのは、開発しただけが知っている。

find_element_by_xpathで要素を指定する時はその要素は上から数えて何回目に出現してるか?を注意してみてほしい

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?