本記事では、Seleniumで子要素を取得する方法について解説します。
親要素と子要素とは
そもそも、子要素とは何かについて確認しておきたいと思います。
以下はYahoo!JAPANのトップページです。左のほうに「ショッピング」「ヤフオク」などのメニューが表示されています。
左側メニューのHTMLは以下のようになっています。
<!-- これは親要素 -->
<div class="parent">
<ul>
<li>
<div>
<!-- これが1つ目の子要素 -->
<span class="child">ショッピング</span>
</div>
</li>
<li>
<div>
<!-- これが2つ目の子要素 -->
<span class="child">ヤフオク!</span>
</div>
</li>
</ul>
</div>
親要素は外側の枠組みのような役割を果たし、その中に各メニューが入っています。このように、何かしらの要素の下の階層に位置するものを「子要素」といいます。
子要素の取得
子要素を取得する手順は、以下のようになります。
パターン1:子要素が1つの場合
例えば、上記HTMLから「ショッピング」を取り出すとします。この場合、
parent = driver.find_element(By.CLASS_NAME, 'parent1') # 親要素を取得
child = parent.find_element(By.CLASS_NAME, 'child') # 子要素を取得
これで子要素を取得することができます。
パターン2:子要素が複数ある場合(テーブル・リスト)
上記HTMLから「ショッピング」を取り出します。このとき、「parent1」クラスには、同名の子要素が複数存在しますので、先ほどの方法ではうまく取得することができません。
そこで、親要素を取得し、親要素から子要素をリストで取得、リストから対象の要素を取り出すようにします。
parent = driver.find_element(By.CLASS_NAME, 'parent1') # 親要素を取得
child = parent.find_elements(By.CLASS_NAME, 'child') # 子要素をリストで取得
print(child[0].text) # 出力結果:ショッピング
親要素に同名のものがあって指定できないとき
以下のように、同じページ内に同名のテーブルが複数ある場合があります。
<table>
<tr>
<td>りんご</td> <td>100円</td>
</tr>
<tr>
<td>スイカ</td> <td>500円</td>
</tr>
</table>
<table>
<tr>
<td>トマト</td> <td>300円</td>
</tr>
<tr>
<td>にんじん</td> <td>200円</td>
</tr>
</table>
このような場合は、テーブルをXPathで指定して取得したあとに子要素を取得するようにします。先ほどの図の吹き出しにあるXPathを見ても分かる通り、XPathはHTMLのツリー構造で一意に要素を特定するための記法です。
parent = driver.find_element(By.XPATH, '/html/body/pre[3]/table') # 親要素を取得
child = parent.find_elements(By.TAG_NAME, 'td') # 子要素をリストで取得
for elem in child:
print(elem.text)
# 出力結果
りんご
100円
スイカ
500円
パターン1、パターン2で説明した内容においても、親要素をXPathで指定して取得することも可能です。classやidで指定してうまく取得できない場合は、XPathを使うと解決できることが多いです。
まとめ
今回は、Seleniumで子要素を取得する方法について解説しました。
要素の取得がうまくできない場合は、以下記事も合わせて参考にしていただければと思います。
コメント