【Python】スクレイピングにおける要素特定は、XPathかCSSセレクターか

スクレイピングにおいて、HTML要素の特定する手段は、XPathとCSSセレクターの2つがあります。Pythonでスクレイピングを始めた当初、どっちで要素を特定するか迷いました。迷わないように参考になる情報をまとめておきました。

XPathとCSSセレクターの比較

XPathかCSSセレクターかですが、ライブラリから見るとCSSセレクターの一択な感があります。しかし、表現の幅の広さでみるとXPathの方が圧倒的に有利です。

ライブラリのXPathとCSSセレクターのサポート状況

この通り使うライブラリによっては、選択の余地なしです。

ライブラリ XPath CSSセレクター
lxml
Beautiful Soup ×
selenium
pyquery ×

ちなみに、lxmlのCSSセレクターは、パッケージ内にlxml.cssselectモジュールという形で提供されています。

XPathとCSSセレクターの要素特定の書き方の比較

下にある通り、CSSセレクターの方が記述が簡単です。とても覚えやすいです。しかし、残念なことに、XPathにできるのに「表現不可」なものが存在します。

ターゲット要素 XPath CSSセレクタ
全要素 //* *
p要素 //p p
p要素の全要素 //p/* p>*
ID属性がfooの要素 //*[@id=’foo’] #foo
クラス属性がfooを含む要素 //*[contains(@class,’foo’)] .foo
title属性を含む要素 //*[@title] *[title]
pの最初の子要素 //p/*[0] p>*:first-child
要素aを持っ全てp要素 //p[a] 表現不可
pと同系列の次の要素 //p/following-sibling::*[0] p + *
pと同系列の前の要素 //p/preceding-sibling::*[0] 表現不可
src属性が”.jpg”で終わるimg要素 //img[ends-with(@src,”.jpg”)] img[src$=”.jpg”]
直下のテキストが文字列であるp要素 //p[text()=”文字列”] 表現不可

Chromeを使って、要素を特定する文字列を簡単に知る方法

Chromeのデベロッパーツールで、要素を特定できる文字列の取得が可能です。

Windowsの場合、F12でツールを開いて、Elementタブを右クリックすると、取得できます。

XPathの記述を取得

取得結果 //*[@id=”rso”]/div[4]/div/div/div[1]/a[1]/h3

CSSセレクターの記述を取得

取得結果 #rso > div:nth-child(4) > div > div > div.yuRUbf > a:nth-child(1) > h3

実際にスクレイピングしていると、CSSセレクターのみ使用

CSSのみを使う理由は、2つあります。

XPathの「直下のテキストが文字列であるp要素」は便利で、これがあればfor文で回す必要がなく、記述も短く済み非常に便利です。ですが、それ以外の特定方法の出番はないです。

CSSセレクターでたどり難い要素は、先に親要素を見つけ、そこからfor文を回して見つけています。for文内で、正規表現を使って、より正確に探り当てます。もちろん遅いです。しかし、WEBサーバにアクセスするスクレイピングは処理スピードを求める必要はないのです。

コメント

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