【Python】Seleniumのfind_elements系はCSS_SELECTORだけ使ってればいい

本ページはプロモーションが含まれています

Seleniumにあるfind_elements系は何種類もあってどれ使うのがいいのって話

find_elementsの種類(Python版)

  • find_elements
  • find_elements_by_class_name
  • find_elements_by_css_selector
  • find_elements_by_id
  • find_elements_by_link_text
  • find_elements_by_name
  • find_elements_by_partial_link_text
  • find_elements_by_tag_name
  • find_elements_by_xpath
    ※”s”のないfind_elementも同じ数あります

答えは「find_elements_by_css_selector」でした

便利とかいくつか理由はあるけどそもそもプログラムとしてそうなんだって証拠はPythonでSeleniumの中身を見れば一目瞭然

まずはサンプルとしてfind_elements_by_idの中身を

    def find_elements_by_id(self, id_) -> List[WebElement]:
        warnings.warn(
            "find_elements_by_id is deprecated. Please use find_elements(by=By.ID, value=id_) instead",
            DeprecationWarning,
            stacklevel=2,
        )
        return self.find_elements(by=By.ID, value=id_)

最後に「find_elements」に集約されている
で、find_elementsの中身はと言うと

    def find_elements(self, by=By.ID, value=None) -> List[WebElement]:
        if isinstance(by, RelativeBy):
            _pkg = '.'.join(__name__.split('.')[:-1])
            raw_function = pkgutil.get_data(_pkg, 'findElements.js').decode('utf8')
            find_element_js = "return ({}).apply(null, arguments);".format(raw_function)
            return self.execute_script(find_element_js, by.to_dict())

        if by == By.ID:
            by = By.CSS_SELECTOR
            value = '[id="%s"]' % value
        elif by == By.TAG_NAME:
            by = By.CSS_SELECTOR
        elif by == By.CLASS_NAME:
            by = By.CSS_SELECTOR
            value = ".%s" % value
        elif by == By.NAME:
            by = By.CSS_SELECTOR
            value = '[name="%s"]' % value

        return self.execute(Command.FIND_ELEMENTS, {
            'using': by,
            'value': value})['value'] or []

ID、TAG_NAME、CLASS_NAME、NAMEがCSS_SELECTORに集約されていることがお分かりだろうか

link_text系は特殊な使い方になるのでとどのつまり”CSS_SELECTOR”か”XPATH”のどちらかを使えばいいって話で、じゃあどっちが正解なの?と聞かれると好みな気がしつつ、WEB系にも少し活かせる”CSS_SELECTOR”がオススメと言うこと
(Seleniumの中身もCSS_SELECTORだしね)

CSS_SELECTORの良いところ

何でも指定できる

そもそもなんでCSS_SELECTORに集約されるかと言うと代用できるから

と言うか”name”の例にしている「[<属性>=”<値>”]」書き方をすればどの属性でも指定できるので極端な話”elements_by”に用意されていない属性だって指定できる

下に書き方と実際に属性を埋め込んで取得の練習ができる表を準備しているので見てほしい

element_byでの代用とサンプル
By サンプルタグ SELECTOR
id sample1 #hoge
class sample2 .hoge
name sample3 [name=”hoge”]
tag_name sample4 td
「[<属性>=”<値>”]」のサンプル
属性 サンプルタグ SELECTOR
data-title sample5 [data-title=”hoge”]
src sample6 [href=”https://javeo.jp/test-page”]

練習はデベロッパーツールで

ChromeならF12押下で表示されるデベロッパーツールのコンソール画面で「document.querySelectorAll(‘<ここにCSS_SELECTOR>’)[0].innerText」を入力すると正しければ下部に取得結果が表示される
※↑の表からCSS_SELECTORをコピペすると「”」が「”」に変換されているので微修正を

複合できる

例えば一つのタグの中に複数の”class”が設定してあるならそれを全て指定することができるし、タグ・class・nameの複合とかもできる

複合指定のサンプル
サンプルタグ SELECTOR例
sample7 td.hoge.fuga[name=”hoge”]
sample8 .hoge[data-label=”b”]
sample9 td.hoge.fuga.piyo

親子要素で指定できる

デベロッパーツールで「selectorをコピー」するとほぼ親子要素の指定で取得されるんで逆に馴染みあるかも

※取得した↑で取得したselector「#e > td.hoge.fuga.piyo

複雑な条件の取得ができるようになること以上に大きな利点としては例えば所定の<li>タグ情報だけを取得する時に便利

とある密林サイトなんかにあるカテゴリーのリストを取得しようと思った時の例

  • すべてのカテゴリー
    • パソコン・周辺機器
      • デスクトップパソコン
      • ノートパソコン
      • タブレット
      • サーバー  
    • ホーム&キッチン
      • キッチン用品
      • 食器・グラス・カトラリー
      • インテリア
      • ラグ・カーテン・ファブリック
      • 家具
      • 収納用品
      • 寝具

SELECTORを「’ul#pc > li’」で指定してforとかで取得すれば「デスクトップパソコン、ノートパソコン、タブレット、サーバー」が取得できる

あとがき

色々準備はされているけど結局使うものは一つって話でした

他にも便利な使い方があれば追加していきます

コメント

タイトルとURLをコピーしました