PythonでScrapyを使ってクローリングをしてみる
前回はurllib2というモジュールを使った簡単なスクレイピングの方法を紹介しました。
今日はScrapyというクローリング+スクレイピングのフレームワークを使って、
ウェブから情報を取ってくる方法をご紹介します。
フレームワークな分、以前紹介した手法よりも大掛かりなものになるので
クローリング対象の大小によって、使い分けするといいでしょう。
スクレイピングとクローリングの違い
クローリング: Webページをリンクを辿り情報を収集すること
スクレイピング: Webページから意図した情報を抜き出す作業のこと
たまに一緒の意味で使う人がいるのですが、厳密にはこのような定義です。
Scrapyとは
Scrapyはクローリングとスクレイピングの両方のフレームワークです。
robots.txtやsitemapをパースしてくれたり、
クローリングの間隔を一括で定義したりできるので便利です。
インストール方法
pipからインストールできます。
$ sudo pip install Scrapy
前準備
以下のコマンドでプロジェクトのフォルダとファイルが生成されます。
$ scrapy startproject rakutenscrapy
設定ファイルを変更します。
# rakutenscrapy/rakutenscrapy/settings.py DOWNLOAD_DELAY = 3 # sleep間隔 ROBOTSTXT_OBEY = True # robots.txtに従うかどうか
出力データのファイルを作成
スクレイピングしたデータはデフォルトでJSONline形式で出力されます。
初めて見る形式でしたが、一行毎にJSONがある形式です。
出力されるデータの構造は以下のように設定できます。
# rakutenscrapy/rakutenscrapy/items.py class RakutenItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() title = scrapy.Field() link = scrapy.Field()
クローリングとスクレイピングのプログラムを作成
# coding: utf-8 from scrapy.contrib.spiders import CrawlSpider, Rule from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor from scrapy.selector import Selector from rakutenscrapy.items import RakutenItem class RakutenSpider(CrawlSpider): name = 'rakuten' allowed_domains = ['http://product.rakuten.co.jp'] start_urls = [http://product.rakuten.co.jp/503169/] rules = [ # 正規表現にマッチするリンクをクローリング Rule(SgmlLinkExtractor(allow=(r'/503169/(.*)', ), restrict_xpaths=('/html', ))), # 正規表現にマッチするリンクをparseメソッドでスクレイピング Rule(SgmlLinkExtractor(allow=(r'/503169/(.*)', ), restrict_xpaths=('/html', )), callback='parse_news'), ] def parse(self, response): sel = Selector(response) match = sel.xpath('//div[@class="proListItemName"]/table') for m in match: item = RakutenItem() item['title'] = m.xpath('.//a/text()').extract()[0] item['link'] = m.xpath('.//a/@href').extract()[0] yield item
Scrapyの実行
コマンドひとつで実行することができます!
$ scrapy crawl rakuten -o rakuten-item.jl
以上で大規模なクローリングとスクレイピングが楽に実装できます。
urllib2とElementTreeを使う方法に比べると、かなり手間に感じますが、
何回かすると、とても簡単にクローリングできるようになるのでぜひやってみてください。
参考
http://orangain.hatenablog.com/entry/scrapy
http://akiniwa.hatenablog.jp/entry/2013/04/15/001411