seleniumのスクレイピングで、要素を取得する時に必ず出てくる手法がfind_elementです。そこで今回は、find_elementのメソッドの種類であったり、使い分け方法を解説していきます。
ここで学べる事:
- seleniumのfind_elementメソッドを使った要素取得方法
Contents
find_elementを使うためのPythonライブラリ
今回説明するのはseleniumのライブラリでfind_elementを使った要素取得の解説です。そのため、必要なライブラリがありますので、以下ライブラリを使うのが前提です。
- seleniumはブラウザ操作を自動化するライブラリです。
- webdriverは、Chrome()やFirefox()といった操作するブラウザを選択します
seleniumを使ったfind_elementの使い分けと種類
(事前知識)単数の要素取得か複数の要素取得かでfind_elementを使い分ける
find_elementで要素を取得する時に、単数の要素か複数の要素取得かどうかでfind_elementを使い分けます。以下の使い分けを行います。
- find_element
- 単数の要素取得を使う場合に使います。指定した条件にマッチする要素が複数ある場合は、最初の要素を取得(返す)します。
- find_elements
- 複数の要素を取得する時に使います。複数の要素はリスト形式で返されるので、取得した要素を見たり、操作するときは、リスト形式の処理が必要。
seleniumでhtmlファイルのソースコードから、ある要素を取得するには様々なメソッドがあります。まず、以下のメソッドがあることを知りましょう。
find_elementのメソッドの種類
要素取得するfind_elementのメソッドには、要素の指定方法によってメソッドが異なります。主に使われるメソッドは以下のようなものがあります。メソッドと使い方を記載します。
- find_element_by_id
- タグ内に記述されたid属性の中身とマッチする要素を探す。
- find_element_by_name
- タグ内に記述されたname属性の中身とマッチする要素を探す。
- find_element_by_xpath
- xpath形式でマッチする要素を探す。
- find_element_by_tag_name
- htmlタグのタグ名でマッチする要素を探す。
- find_element_by_class_name
- タグ内に記述されたclass属性の中身とマッチする要素を探す。
- find_element_by_css_selector
- cssセレクタ形式でマッチする要素を探す。
また、複数の要素取得時に使用するfind_elementsは「s」を「element」に追加したメソッドで記述します。複数の要素取得はリスト形式で要素を取得するので、メソッドの説明がほぼ変わらないため、メソッドの種類のみを記載します。
- find_elements_by_name
- find_elements_by_xpath
- find_elements_by_tag_name
- find_elements_by_class_name
- find_elements_by_css_selector
seleniumを使ったfind_elementの要素取得
では、実際にseleniumを使ったfind_elemntの要素取得を行いましょう。まずはこんなhtmlのソースコードがあったとします。それぞれの要素をfind_elementを使って要素取得していきます。
1 2 3 4 5 6 7 8 9 10 |
// このhtmlソースコードの情報を元にfind_elementで情報を取得する <html> <body> <form id="loginForm" class="form-design"> <input name="username" type="text" /> <input name="password" type="password" /> <input name="submit" type="submit" value="login" /> </form> </body> <html> |
まず、seleniumを使える状態にします。
1 2 3 4 |
// webdriverでChromeを起動⇒そして該当URLをChromeで開く from selenium import webdriver driver = webdriver.Chrome() //chrome起動 driver.get('https://www.xxx取得したいURLを入れましょうxxx.com/')//chromeでページを表示 |
上記を実行することでwebdriverでChromeを起動し、該当URLをChromeで表示することができます。この表示したwebdriverに要素取得を行いましょう。先ほど紹介したhtmlコードの記述情報を元にfind_elementで要素を取得する方法を以下で紹介します。
find_element_by_nameで要素を取得する
find_element_by_nameは、タグ内のname属性に書かれた内容と条件マッチした要素を取得します。
1 2 |
//elemの変数にname属性が、usernameに一致した要素を格納する elem = driver.find_element_by_name('username') |
find_element_by_xpathで要素を取得する
xpathは、ツリー構造となるxml/html形式から、要素や属性を指定するための構文です。先ほど紹介したfind_element_by_nameとは、要素を指定する構文が異なります。
1 2 |
//htmlソース内の最初のフォームタグを要素取得 elem_form = driver.find_element_by_xpath("//form[1]") |
ちなみに、上記の場合は最初のフォームタグを取得しますが、以下のようにid属性を条件に要素を取得することも可能です
1 2 |
//elem_formの変数に、id属性がloginFormにマッチする要素を取得 elem_form = driver.find_element_by_xpath("//form[@id='loginForm']") |
他の要素取得方法に比べてxpath形式は難しいと感じる方も多いかと思います。仕組みを理解せずに、簡単に指定してみたい場合は、windowsであればブラウザを開いた状態でF12キーを押し、デベロッパーモード(Chromeの呼称)を開きましょう。デベロッパーモードで取得した要素に対して「右クリック」⇒「コピー」⇒「xpathをコピー」で箇所を特定することが可能です。
find_element_by_tag_nameで要素を取得する
1 2 |
//elem_tagの変数にタグの名前がformのタグ要素を取得する elem_tag = driver.find_element_by_tag_name("form") |
find_element_by_class_nameで要素を取得する
1 2 |
//elem_classの変数にclass属性の値がform_designになっている要素を取得する elem_class = driver.find_element_by_class_name("form-design") |
find_element_by_css_selectorで要素を取得する
1 2 |
//elem_selectorの変数に,formタグのclass属性がform_designになっている要素を取得する elem_selector = driver.find_element_by_css_selector("form.form-design") |
Xpathと同様にselector部分をデベロッパーモードで調べることが可能です。windowsであればブラウザを開いた状態でF12キーを押し、デベロッパーモード(Chromeの呼称)を開きましょう。デベロッパーモードで取得した要素に対して「右クリック」⇒「コピー」⇒「selectorをコピー」で箇所を特定することが可能です。
兄弟要素をfind_element_by_css_selectorで取得する
find_elementで要素を取得する時に、要素を取得する条件で兄弟要素を取得したいと思う時が実務上発生することは想像ができます。その時のために、find_element_by_css_selectorで兄弟要素を指定します。以下のソースコードがあったとします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
//兄弟要素を取得する場合のhtmlソースコードのサンプル <p class="author"> xxxxさんは以下の本を出版しております。 </p> <p class="book"> <ul> <li>タイトル1:ーーー分析入門</li> <li>タイトル2:スクレイピング基礎編</li> <li>タイトル3:データ解析</li> <li>タイトル4:Pandasでデータ分析</li> </ul> </p> <p class="last"> 来年も本を出版予定です。 </p> |
上記のタグからclass属性のauthorから見た隣接する直後の兄弟要素は、bookが記述されたclass属性です。その場合、以下のように記述を行います。
1 2 |
// 隣接する直後の兄弟要素を指定する場合は、cssセレクターに「+」を追記して指定する elem_bro = driver.find_element_by_css_selector("p.book + p") |
上記の隣接する直後の兄弟要素だけでなく、すべての後ろの兄弟要素を取得する場合は「~(チルダ)」を使います。
1 2 |
// 隣接する直後の兄弟要素を指定する場合は、cssセレクターに「+」を追記して指定する elem_bro_all = driver.find_element_by_css_selector("p.book ~ p") |
まとめ
selenium自体は他のスクレイピングより、処理が遅いなんて言われますが、遅いことを除けば万能だと思います。seleniumのスクレイピングではfind_elementで要素が取得できることはファーストステップなので、しっかり押さえておきましょう。