XPath 基礎 (1)

みなさんもご存知の通り、Web ページは HTML で書かれています。

ですので、スクレイピングしたりクライアントサイドで動的なページを作ったりするときには、自分が処理したいその部分を何らかの方法で指定する必要があります。

jQuery 使いの方に馴染みが深いのは CSS セレクタかと思います。

.block {
  width: 100px;
}

.block がセレクタですね。 「class 属性に block が指定されている要素」を指定するものです。

CSS セレクタでもかなり複雑な指定ができますが、XPath を使用するとさらに複雑な指定ができるようになります。

CSS セレクタでは、

  • タグ名で指定した要素 (div, p)
  • id 属性や class 属性に、指定した文字列が設定されている要素 (#hoge, .hoge)
  • 任意の属性の値が任意の文字列と一致する要素 (div[class="hoge"])
  • 指定した要素の下位、直下、兄弟などの要素 (div p a, div > p)

といった指定の仕方が基本となります。

XPath でも同じように、タグ名、構造、属性値などで要素を指定することができます。

XPath では、ロケーションパスという表現を使って要素を指定します。例えば、

//div

これは全部の div タグを指定することになります。

XPath では、ディレクトリ構造を指定するように、/ (スラッシュ) で要素を区切って指定します。

//div/p/a

上記であれば、「すべての div タグの直下にある p タグの直下にある a タグ」ということになります。

最初の / はルートノードを意味します。ルートノードとはなんぞやということですが、HTML 文書は入れ子の構造であり、つまりツリー構造になっています。
その一番上の頂点がルートノードです。ですので、

/div

としてしまうと、それは頂点の直下の div ということになってしまいますので、これに合致する要素はありません。

// は、「自身および子孫」を表します。なので、//div はすべての div タグを意味するというわけです。

//div//p

上記のようにすれば、「すべての div タグのそれぞれの子孫にある p タグ」ということになります。

<div id="d1">
  <p>...</p>
  <div id="d1-1">
    <p>...</p>
    <section>
      <p>...</p> <!-- この p は div/p ではマッチしない -->
    </section>
  </div>
</div>
</html>