XPathとは?
XMLやHTMLなどから欲しい部分を指定して取得することができる簡易言語です。XSLTなどでXML操作に利用されるのはもちろん、現在はスクレイピング用途でも幅広く利用されています。
XPathのメリット
CSSセレクタで取得する場合に比べてXPathの方が若干要素の指定が柔軟にできます。
- 階層構造を辿って要素を指定する。
- 正規表現を使って要素を指定する。
XPathのデメリット
- Scrapyでは使えますが、BeautifulSoupでは使えない。
XPath Playground
手軽にXPathを試せます。
https://scrapinghub.github.io/xpath-playground/
基本
ロケーションパス
要素までの階層の道のりを示したものを呼びます。
例えば、h2などの各要素はノードテストと呼びます。スラッシュで区切ると階層を辿ることが可能です。これを
1 |
/ノードテスト/ノードテスト/ノードテスト |
最初から取得
1 |
/html/body/h2 |
途中から取得
スラッシュ2つであれば、直接要素にアクセスできます。
1 |
//h2 |
軸
軸とは、親、子、子孫、先祖など様々な要素を指定できるロケーションパスの指定法です。
1 |
/軸::ノードテスト/軸::ノードテスト |
軸 | 説明 | ||
---|---|---|---|
parent | 親要素(子孫要素も含めて)取得します。
|
||
ancestor | 先祖要素(子孫要素も含めて)全て取得します。(取得結果は複数になります。)
|
||
ancestor-of-self | 自分自身も含めた先祖要素を全て取得します。(ancestorと違い、取得する複数の結果の中に自分自身のnodeも追加されるイメージです。)
|
||
preceding | 先祖を除く全ての前の要素。(例えばHTMLで言えば、全ての要素の先祖であるhtmlタグは絶対に取得されることはないです。)
|
||
preceding-sibling | 前にある全ての兄弟要素(つまり、同じ階層の前の要素)
|
||
child | 子要素
|
||
following | 後ろの全ての要素
|
||
following-sibling | 後ろにある兄弟要素
|
||
descendant | 後ろの子孫要素
|
||
descendant-or-self | 自分自身を含む後ろの子孫要素
|
||
self | 自分自身の要素
|
||
attribute | 自分自身の属性の値を出力
|
なお、祖先であれば祖父はもちろんですが、親も含みますし、子孫であれば孫はもちろんそうですが、子も含みます。
属性の指定して要素を特定する。
1 |
要素[@属性=属性値] |
以下のHTMLがあるとする。
1 |
<a class="item is-active" href="/">テスト</a> |
以下のように指定する。
1 |
//a[@class="item is-active"] |
テキストを取得する。
1 2 3 |
//a[@class="item is-active"]/text() テスト |
属性の値を直接取得
1 |
要素/@属性 |
上記のように指定すれば属性の値を直接取得できます。
1 |
//h3/a/@href |
こうすればh3の下にあるaタグのhref属性の値を取得できます。
要素を絞り込む
含む
containsという述語を利用します。例えば、href属性(URL)の中に「A07TN4D3HG」というコードが含まれている要素だけを抽出したい場合は以下のように指定します。
1 |
//a[contains(@href,"A07TN4D3HG")] |
テキスト検索
1 |
//a[contains(text(),"Python")] |
なお、テキスト検索は大文字小文字を区別するので注意が必要です。
含まない
1 |
//a[not(contains(@href,"A07TN4D3HG"))] |
notという述語で囲えば逆に含まない要素を検索できます。
複数条件での絞り込み
以下は、hrefにA07TN4D3HGを含みかつidにlink2を含む場合を示しています。
1 |
//a[contains(@href,"A07TN4D3HG") and contains(@id,"link2")] |
前方一致検索
1 |
//a[starts-with(@href,"http://www.amazon.co.jp/dp/B07SRLR")] |
後方一致検索(XPath2.0以降のみ)
1 |
//a[ends-with(@href,"4M")] |
XPath2.0以降しか対応していないので対応していないブラウザも多いのであくまで参考までです。
list要素の取得方法
番号を指定して取得
前から何番目の値を取得するか指定している。
1 |
//li[position() =2] |
もしくは以下のようにも書けます。この方が簡潔なので望ましいです。
1 |
//li[2] |
最後の要素を取得
1 |
//li[position() =last()] |
三番目以降の要素を取得
大なり記号も使えます。
1 |
//li[position() >2] |
この記事へのコメントはありません。