Python
xpath
scraping
Scrapy
crawler

Python Scrapy でウェブサイトからデータを抽出する際の、xpathまとめ

More than 1 year has passed since last update.

Python のモジュール、Scrapyを用いれば、ウェブサイトのデータを、リンクを巡回しながら順次自動的に取得できます。

ウェブサイトから所望のデータを抽出するには、欲しいデータの場所 を指定してあげなければなりません。

指定するものをセレクタと呼びます。Scrapyではcssと、xpathの指定方法がありますが、今回はxpathのして方法について説明します。


準備

Scrapyをpipでインストールします。


commandline

$ pip install scrapy



Scrapy Shell

Scrapy には、Scrapy shellと呼ばれる、インタラクティブにデータ抽出を検証できるツールがあります。


commandline

scrapy shell "http://hogehoge.com/hoge/page1"


のように指定すると、指定したページの情報が入ったresponseというインスタンスを受け取った状態でpythonのインタラクティブシェルが立ち上がります。実際にスパイダー(クローラー)を開発する際も、このresponseインスタンスからデータを抽出していきます。


実践


responseのxpathメソッド

基本的に、このような構文でデータを抽出していきます。


shell

>>> response.xpath('//title/text()')

[<Selector (text) xpath=//title/text()>]

この例では、受け取ったhtml文章の中の、全てのtitleタグ(//title)の、本文(text())を抽出しています。ただし、このままですと上記のように、返り値はセレクタです。文字を得るには.extract()を用います。


shell

>>> response.xpath('//title/text()').extract()

[u'exsample title']


抽出データの文字列化

抽出データはリストですので、配列指定などで文字列にします。


shell

>>> response.xpath('//title/text()').extract()[0]

u'exsample title'

ちなみにこのu'文字列'はユニコードという意味です。pythonでは文字列をユニコードで扱います。

複数のウェブサイトを巡回していると、指定したxpathがどこにも該当しない場合があります。その状態で上記のように配列の0番目 response.xpath(hoge).extract[0] を指定するとエラーとなりますので、これを回避するために


shell

>>> item['hoge'] = response.xpath('//title/text()').extract_first()


などします。

また、得られた配列[u'hoge1', u'hoge2', u'hoge3']などを全て連結して文字列として得たければ


shell

>>> extract_list = [u'hoge1', u'hoge2', u'hoge3']

>>> ''.join(extract_list)
u'hoge1hoge2hoge3'

とやればできます。


xpath集

xpath
内容

//div
全てのdivタグ

//div[@class='aaa']
全ての、classに'aaa'を持つdivタグ

//div[@id='aaa']/text()
全ての、idが'aaa'のdivタグ -> の本文

//a[text()='aaa']/@href

全ての、本文が'aaa'のaタグ -> のhref属性値

//div/tr
全てのdiv -> 子要素のtrタグ

//table/tr/th[text()='price']/following-sibling::td[1]/text()
全てのテーブル -> その行 -> priceというフィールド -> そのデータ要素のうち1番目 -> の本文

最後のtableに関するxpathは、ウェブページの表から、フィールドを指定(上記の場合はprice、金額の部分)して値を取ってこれるので便利です。

tdの指定ですと、同じ行のtd要素をどんどんとってしまうので、td[1]として1番目を抜き出しています。[1]です。[0]じゃないです。