Scrapyを使ってクローリング、スクレイピングをやってみた話
はじめに
普段はJavaを主に利用しているのですが、ちょっとした作業で使うのにはちょっと面倒臭いものです。
今回はあるサイトからデータを取得したいとの相談を受けまして、Pythonにより実装されたクローリング、スクレイピングのフレームワークであるScrapyを利用してやってみました。
なお、Spiderクラスのみの最小の構成で動作させているため、Itemクラスは作成していません。
インストール
pip3 install scrapy
プロジェクトの作成
scrapy startproject first_scrapy New Scrapy project 'first_scrapy', using template directory '/usr/local/lib/python3.6/site-packages/scrapy/templates/project', created in: /Users/XXXXX/first_scrapy You can start your first spider with: cd first_scrapy scrapy genspider example example.com cd first_scrapy tree . . ├── first_scrapy │ ├── __init__.py │ ├── __pycache__ │ ├── items.py │ ├── middlewares.py │ ├── pipelines.py │ ├── settings.py │ └── spiders │ ├── __init__.py │ └── __pycache__ └── scrapy.cfg 4 directories, 7 files
設定の変更
settings.pyにはScrapyの様々なオプションを指定できます。
指定可能なオプションは公式から確認できます。
今回は以下のオプションのみ変更しています。
- DOWNLOAD_DELAY:1つのページをダウンロードしてから、次のページをダウンロードすするまでの間隔(単位:秒)
- ROBOTSTXT_OBEY:robots.txtがある場合は、それに従うかどうか
- FEED_EXPORT_ENCODING:出力ファイルの文字コード
DOWNLOAD_DELAY = 3 ROBOTSTXT_OBEY = True FEED_EXPORT_ENCODING = 'utf-8'
Spiderの作成
ガイドメッセージに従いSpiderを作成していきます。
Spiderは「scrapy.Spider」のサブクラスで、最初にアクセスするURLと、どのようにHTMLからデータを抽出するかを定義します。
scrapy genspider モジュール名 クローリング対象のドメイン
scrapy genspider example example.com Created spider 'example' using template 'basic' in module: first_scrapy.spiders.example
以下のようなコードが作成されます
# -*- coding: utf-8 -*- import scrapy class ExampleSpider(scrapy.Spider): name = 'example' allowed_domains = ['example.com'] start_urls = ['http://example.com/'] def parse(self, response): pass
start_urlsには最初にアクセスするURLを指定します。
この処理を実行するとstart_urlsにアクセスした結果を引数としてparseメソッドが実行されます。
responseに対して、XPathかCSS形式でセレクタを指定することで欲しい情報を取得することが可能となっています。
具体的には以下のイメージです。
def parse(self, response): ids = response.xpath('//div[@class="example"]/@id').extract() for id in ids: yield { "ID" : id } pass
scrapy runspiderを実行することでSpiderを実行することができます。 以下の例の場合、結果がexample.csvに出力されます。
scrapy runspider --nolog first_scrapy/spiders/example.py -o example.csv
なお、scrapy.Requestをコールすることで次のurlを引き続きスクレイピングさせることが出来ます。
# 同じメソッドでパースさせる場合 yield scrapy.Request(url) # 別のパースメソッドでパースさせる場合 yield scrapy.Request(url ,callback=self.XXXXX)
トラブルシューティング
インストール時のエラー
Windows環境でpip3にてインストールを行う際に以下のエラーが発生しました。
error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": http://landinghub.visualstudio.com/visual-cpp-build-tools
2018/06/22現在、エラーのurlではダウンロードできなくなっていますが、microsoftからダウンロードできます。
scrapy runspiderの実行時エラー
scrapy runspiderを実行する際に以下のエラーが発生しました。
ImportError: No module named win32api
公式にもpywin32をインストールするように記載があったので、大人しくインストールしました。