LoginSignup
1
0

More than 1 year has passed since last update.

スクレイピングのためのXpath超・超基本

Last updated at Posted at 2022-03-22

Xpathとは

XML形式の文書のなかの特定の要素を一意に指定するための構文である。スクレイピングでは主にhtmlのスクリプトに対して使われる。

Xpathの記法

基本

htmlは入れ子構造の構文が用いられる。階層構造を辿るように書く点はディレクトリの絶対パスと同様、例えば

サンプルコード(長いので折りたたみます)
<!DOCTYPE html>
<html lang="ja">
<head>
    <style>
        .theme{
            color : green;
        }
        .subtitle{
            color : violet;
        }
        .chemical{
            color : skyblue;
        }
        
    </style>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>植物</title>
</head>
<body>
    <p class="theme">
        <b>植物</b>
    </p>

    <p>肥料</p>
    <h1 class="subtitle">肥料の三要素</h1>
    <h2 class="chemical">窒素</h2>
    <ul id="窒素">
        <li>光合成の促進</li>
        <li>葉や茎の成長</li>
    </ul>
    <h2 class="chemical">リン酸</h2>
    <ul id="リン酸">
        <li number="1">開花</li>
        <li number="2">結実</li>
    </ul>
    <h2 class="chemical">カリウム</h2>
    <ul id="カリウム">
        <li number="1">根の成長</li>
        <li number="2">植物の免疫力</li>
    </ul>
    <h3>微量元素</h3>
    <ol>
        <li number="1"></li>
        <li number="2">マンガン</li>
        <li number="3">ホウ素</li>
        <li number="4">亜鉛</li>
    </ol>
</body>
</html>

↑このページで「<h3>微量元素</h3>」という要素を指定したいときは

/html/body/h3
出力
<h3>微量元素</h3>

とすれば良い。
途中までを省略して "//h3" とすることもできる。
ちなみに上のコードで下のようなページが作れます。内容は100%自分の趣味です

ページのスクリーンショット

スクリーンショット 2022-03-18 23.39.30.png

テキストのみ抽出

「微量元素」という文字列のみを抽出したい場合は text() をつけて

/html/body/h3/text()
出力
微量元素

兄弟要素を属性で指定

上の例では「鉄」「マンガン」「ホウ素」「亜鉛」は全て/html/body/ol/liであり、number属性を用いなければ区別できない。そこで

構文
要素[@属性 = 属性値]

という構文を用いる。

「マンガン」を指定したいとき
/html/body/ol/li[@number = "2"]/text()
出力
マンガン

指定した属性値を持つもの以外をまとめて指定

[]の中身をnot()で囲うことで否定形となる。

属性値"1"を含むもの以外をまとめて指定
/html/body/ol/li[not(@number = "2")]/text()
出力
鉄
ホウ素
亜鉛

number属性が1,3,4のものが抽出されている。

リスト内の要素に属性が当てられていない場合

上の例では/html/body/ul[@id="窒素"]/liに"<li>光合成の促進</li>"と"<li>葉や茎の成長</li>"があるが、この2つは属性で区別できない。このような場合は

/html/body/ul[@id="窒素"]/li[1]
出力
<li>光合成の促進</li>

のようにインデックスで取得できる。

複数選択したい場合は

//li[1 or 2]

とは書かず、

//li[position()=1 or position()=2]

とする

  • position()=last     最後の要素を取得
  • position()>3     4番目以降の要素を取得
    なども可能

知っておくと便利なもの

属性値が指定した文字列と前方一致

構文
要素[starts-with(@属性,"指定した文字列")]

ends-withで後方一致になる。(xpath2.0から実装)

属性値に指定した文字列を持つ要素を抽出

構文
要素[contains(@属性,指定した文字列)]

"@属性"を"text()"に変え、[contains(text(),"文字列")]でテキスト内に指定した文字列を持つ要素を抽出できる。この場合、@(アットマーク)は使わない。

論理積的な記述

構文
要素[条件1 and 条件2]
例,class属性値にhogehoge1という文字列をふくみ、hogehoge2という文字列を含まない
li[contains(@class,hogehoge1) and not(contains(@class,hogehoge2))]

andではなくorを使うと論理和的な記述になる。

省略しない記法

p/a

は、

p/child::a

の省略形である。どちらも「pの子要素のa」という意味は変わらないが、「子要素の」の部分が上の例では省略されているが下の例では「child」と明示されている。このような前後のノードの関係性を示すものをという。

構文
/軸::ノード

であり、childは軸のデフォルトとして設定されているため、軸に何も指定しないと上の例のように子要素を辿る。

便利なサイト

  • Xpath Playground
    テキストをコピペしてxpathを欄内に入力すると指定された要素が出力される。xpathのデバッグに使えて便利
1
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0