Python

Python - 簡単にクロール&スクレイピングができてしまうライブラリ Scrapy

Scrapyとは、スクレイピング技術とWebクローリングの両方を提供しているPython製のフレームワークです。

Pythonで簡単にクロール&スクレイピングができてしまうクローラー「Scrapy」

Scrapyとは?

Scrapyとは、スクレイピング技術とWebクローリングの両方を提供しているPython製のフレームワークです。様々なWebページを収集してそれらのページを解析するまでの一連の動作が、ひとつのフレームワークに詰まっています。

データマイニングをするためのデータ集めにかかせないツールの1つです。

実際にスクレイピーを導入してみた

pipが入っていれば、コマンド1つです(pip導入方法は別記事で)

pip install scrapy

これだけで、導入は終了

チュートリアルの日本語メモ

http://doc.scrapy.org/en/latest/intro/tutorial.html

このチュートリアルの日本語メモをつらつらメモ。

全体的な流れとしては、

  • Scrapyプロジェクトの新規作成
  • 抽出するItemの定義
  • クロールするためのスパイダーと抽出するアイテムの設定
  • 抽出されたItemsを保存するためのItem Pipelineの設定

となっています。

Scrapyプロジェクトの新規作成

セットしたいフォルダにて以下のコマンドを叩きます。

scrapy startproject tutorial

今回はプロジェクト名をtutorialとしました。これにより、tutorialフォルダが作成され、以下のフォルダ構成となります。

tutorial/
    scrapy.cfg
    tutorial/
        __init__.py
        items.py
        pipelines.py
        settings.py
        spiders/
            __init__.py
            ...

各ファイルやディレクトリの説明

  • scrapy.cfg:プロジェクトのConfigファイル
  • tutorial/:プロジェクトのPythonモジュールで、ここからimportして使用する
  • tutorial/items.py:itemsのファイル
  • tutorial/pipelines.py:pipelineのファイル
  • tutorial/setting.py:settingのファイル
  • tutorial/spiders/:スパイダーを配置するディレクトリ

Itemの定義 何を抽出したいのか?

今回はTutorialに合わせて、dmoz.orgをクロールする場合で考えていきます。抽出するItemのデータタイプを定義するため、/tutorial/items.pyに以下のクラスを追加

import scrapy

class DmozItem(scrapy.Item):
    title = scrapy.Field()
    link = scrapy.Field()
    desc = scrapy.Field()

Spiderの設定 どのように抽出するか?

続いてWebページをどのように抽出するかの設定を行います。Spiderクラスのサブクラスとして、以下の3つのメイン属性を定義する。

  • name:Spiderのユニークな名前をつける
  • start_urls:クロールを行う初期ページのURLを設定
  • parse:クロールを行った後の解析するための関数の定義

Tutorialの例として、以下のdmoz_spider.pyを/tutorial/spiders/の下に作成する。

HTMLをそのまま保存する例

import scrapy

class DmozSpider(scrapy.Spider):
    name = "dmoz"
    allowed_domains = ["dmoz.org"]
    start_urls = [
        "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",
        "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"
    ]

    def parse(self, response):
        filename = response.url.split("/")[-2] + '.html'
        with open(filename, 'wb') as f:
            f.write(response.body)

以下のコマンドを叩き、実行する

scrapy crawl dmoz

HTMLをパースして指定した要素を抽出する例

import scrapy

class DmozSpider(scrapy.Spider):
    name = "dmoz2"
    allowed_domains = ["dmoz.org"]
    start_urls = [
        "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",
        "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"
    ]

    def parse(self, response):
        for sel in response.xpath('//ul/li'):
            title = sel.xpath('a/text()').extract()
            link = sel.xpath('a/@href').extract()
            desc = sel.xpath('text()').extract()
            print title, link, desc

以下のコマンドを叩き、実行する

scrapy crawl dmoz2

最後にitemをスクレイプしたものをitemに渡す例

import scrapy

from tutorial.items import DmozItem

class DmozSpider(scrapy.Spider):
    name = "dmoz3"
    allowed_domains = ["dmoz.org"]
    start_urls = [
        "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",
        "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"
    ]

    def parse(self, response):
        for sel in response.xpath('//ul/li'):
            item = DmozItem()
            item['title'] = sel.xpath('a/text()').extract()
            item['link'] = sel.xpath('a/@href').extract()
            item['desc'] = sel.xpath('text()').extract()
            yield item

以下のコマンドを叩き、実行する

scrapy crawl dmoz3 -o items.json

チュートリアルとしては以上です。次回以降、スクレイピングはどう設定するの?とかを実際にどこかのサイトを例にやっていきたいと思います。

データの出力

デフォルトではjsonファイル形式

setting.pyの設定

DOWNLOAD_DELAY=5
ROBOTSTXT_OBEY=True

Spiderの作成

scrapyコマンドでspideerのテンプレートを作成する

scrapy genspider -t basic example example.com

-Python