23
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

lxmlメモ

Posted at

はじめに

今回の内容はスクレイピングする上で用いたとあるライブラリについての個人的感想です。
どんなことができるのか、使ってみた感想をつらつらと書いていきます。

スクレイピングとは

Web上のページから情報を引き抜くこと。機械学習など大量のデータが欲しい時に、データの取得をプログラミングで自動化できるのでとても便利なものである。

lxmlとは

スクレイピングを実現するためのPythonモジュールのひとつ。他にもhtmllibやBeautiful Soupなどがある。

特徴

  • とにかく高速、おそらくモジュールがCを使って書かれたため?
  • HTMLの要素をDOM(Document Object Model)構造に変換する
  • XPath(次で説明)というものを使って抜き取る要素を指定

使い方

lxmlで要素を抜き取りたいときは、XPathというもので要素の場所を指定する必要がある。
XPathの使い方は[こちら][sansyou1]のものを引用しつつ説明する。

XPath(XML Path Language)とは、XML形式の文書から、特定の部分を指定して抽出するための簡潔な構文(言語)です。HTML形式の文書にも対応します。
CSSではセレクタを使ってHTML文書内の特定の部分を抽出しますが、XPathはより簡潔かつ柔軟に指定ができるとされています。

例としてbody以下のリンク要素(hogeクラス)を取り出す書き方を挙げる。

  • CSSセレクタ: html > body a.hoge
  • XPath: /html/body//a[@class="hoge"] または //a[@class="hoge"]

このようにXPathは要素を階層的に指定できる。
さらにXPathでは絶対パス形式と相対パス形式で要素を指定できるので柔軟に要素を抜き取ることができる。

具体例として以下のようなHTMLファイルから要素を抜き取るとする。

sample.html
<html>
<head>
    <title>sample page</title>
</head>
<body>
    <div class="test1">
        <h1>Hello World!!</h1>
    </div>
    <div class="table">
        <table border="1">
          <tr>
            <th>名前</th>
            <th>一言</th>
          </tr>
          <tr>
            <td>サンプル1</td>
            <td>よろしく</td>
          </tr>
          <tr>
            <td>サンプル2</td>
            <td>はじめまして</td>
          </tr>
                    <tr>
            <td>サンプル3</td>
            <td>これはテストです</td>
          </tr>
        </table>
    </div>
</body>
</html>

このとき、テーブル内の一言を抽出したい場合は、次のようにXPathを指定する。

//table/tr/td[2]

もしサンプル2が発している「はじめまして」を抽出するなら//td[4]と指定しても良い。
ただし、tdの数の変動を考慮するならば次のように指定する。

//table//td[contains(*,'サンプル2')]/following-sibling::td[1]

こうすることで中身がサンプル2であるtdの後ろにある要素(今回はtd)を抽出することができる。
XPathにはこうした細かい条件を指定できる関数もあるので、非常に便利である。
ここまでをコードとしてまとめる。

import lxml.html
import requests                        # Webページのソースを取得するのに用いる。今回はこれについての説明は省く

url = 'http://example.com/'            # URLの一例、今回は上のsample.htmlを指すものとする

r = requests.get(url)                  # URLにあるページのソースを取得
html = lxml.html.fromstring(r.text)    # 取得したソースをHtmlElementオブジェクトに変換

td = html.xpath("//table//td[contains(*,'サンプル2')]/following-sibling::td[1]")
# >>> print(td)
# '<td>はじめまして</td>'

指定された要素の中身(ex.文字列やURL)を抽出するには以下の文を最後に追加する。

text = td.text()

ただし、もしtdの中身がはじめまして<br />僕はサンプル2ですの場合、text()ははじめましてしか抽出できない。そういったときは次のようなメソッドを使う。

text = td.text_content()

こうするとtextにははじめまして僕の名前はサンプル2ですが代入され、要素内の全文字列を取得することができる。
その他様々なデータの抽出方法は[こちら][sansyou2]を参考に

感想

大量のデータをとるときでもわずか数分で取得できたのは神だった。
スクレイピングする際は「とりあえずlxml」の気持ちで生きていきたい。

参考文献

[XPathのまとめ、要素の参照方法いろいろ][sansyou1]
[Python(lxml)でhtmlを処理する まとめ][sansyou2]
[sansyou1]:https://webbibouroku.com/Blog/Article/xpath
[sansyou2]:http://www.cafe-gentle.jp/challenge/tips/python_tips_003.html

23
20
0

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
23
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?