たなちの備忘録

自分の知識をストックしていくためのブログ

【scrapy入門】インストールからspider実行まで

スポンサーリンク

scrapyの調べ物をしたときのメモ。


scrapyとは

WebCrawlerのフレームワークのひとつ。
WebCrawlerとは、ロボット型検索エンジンがWEB上のファイル(HTML文書だけでなく、画像・PDFまで含む全般)を収集するためのプログラムのこと。
参考:
クローラーとは | SEO用語集:意味/解説/SEO効果など [SEO HACKS]

scrapyのインストール

$ sudo pip install scrapy

こんなメッセージが。

build/temp.linux-x86_64-2.7/_openssl.c:434:30: fatal error: openssl/opensslv.h: そのようなファイルやディレクトリはありません
    compilation terminated.
    error: command 'x86_64-linux-gnu-gcc' failed with exit status 1

libssl-devをインストールして解決

sudo apt-get update && sudo apt-get install libssl-dev

プロジェクトの作成

$ scrapy startproject tutorial

実行結果。spiderが実行できるようになりました。

New Scrapy project 'tutorial', using template directory '/usr/local/lib/python2.7/dist-packages/scrapy/templates/project', created in:
    /home/username/tutorial

You can start your first spider with:
    cd tutorial
    scrapy genspider example example.com

ツリー構成

$ tree tutorial/
tutorial/
├── scrapy.cfg
└── tutorial
    ├── __init__.py
    ├── items.py
    ├── middlewares.py
    ├── pipelines.py
    ├── settings.py
    └── spiders
        └── __init__.py

2 directories, 7 files

scrapyの構造

f:id:chi_tana:20161225095344p:plain
Architecture overview — Scrapy 1.0.7 documentationから引用

図を見る限り、コンポーネントは次の5つ。
どのファイルがどんな役割をしているのかをメモ
qiita.comを参考にさせていただきました。

ScrapyEngine
 コンポーネント間のデータフローを制御
 特定のアクションが発生したらイベントの発生させる
Spider
 ユーザーが作成するカスタムクラス
 取得したいURL、抽出したい内容を記述する
 ダウンロードしたコンテンツをもとにItemを作成
 start_urlsを書いてクローリングを開始するURLを指定
Scheduler
 ScrapyEngineからリクエストを受け、キューイングとスケジューリングを行う
 キューイングとは、相手の反応を待たずにキューと呼ばれるデータ領域にデータを格納し次の処理に向かうこと
Downloader
 ダウンロードを行う
ItemとPipeline
 Spiderによって抽出されたアイテムを出力する
 データのparse(クレンジング)や検証を行う

spiderの実行

上記サイトのコードを引用させていただきます。

tutorial/tutorial/spiders/qiita_spider.pyを作成します。

# -*- coding: utf-8 -*-

import scrapy


class QiitaSpider(scrapy.Spider):
    name = 'qiita_spider'

    # エンドポイント(クローリングを開始するURLを記載する)
    start_urls = ['http://qiita.com/advent-calendar/2015/categories/programming_languages']

    custom_settings = {
        "DOWNLOAD_DELAY": 1,
    }

    # URLの抽出処理を記載
    def parse(self, response):
        for href in response.css('.adventCalendarList .adventCalendarList_calendarTitle > a::attr(href)'):
            full_url = response.urljoin(href.extract())

            # 抽出したURLを元にRequestを作成し、ダウンロードする
            yield scrapy.Request(full_url, callback=self.parse_item)

    # ダウンロードしたページを元に、内容を抽出し保存するItemを作成
    def parse_item(self, response):

        urls = []
        for href in response.css('.adventCalendarItem_entry > a::attr(href)'):
            full_url = response.urljoin(href.extract())
            urls.append(full_url)

        yield {
            'title': response.css('h1::text').extract(),
            'urls': urls,
        }

このコマンドで実行。-oは出力結果をJSON形式でファイルに保存するオプション。

/tutorial$ scrapy runspider tutorial/spiders/qiita_spider.py -o advent_calendar.json

実行結果は/tutorial/advent_calendar.jsonに作成される。

[
  {
    "urls": [],

    "title": ["akuaputane Advent Calendar 2015"]
  },
  {
    "urls": [
      "http://qiita.com/jwhaco/items/ba06026dc0db20691132",
      "http://qiita.com/jwhaco/items/f9774243a998415f53c7",
      "http://qiita.com/t-mochizuki/items/61e6a7d530b084ba77e5",
      "http://qiita.com/t-mochizuki/items/54cd1b345944759c58d5",
      "http://qiita.com/seratch@github/items/243e99117429bda5f172",
      "http://qiita.com/Peranikov/items/624df5fbf036d521ca74",
      "http://qiita.com/ryoppy/items/476467a4b709f011fb8f",
      "http://blog.goo.ne.jp/hishidama/e/cb97eeae5c3e0fabf317f5e7eba9eee2",
      "http://qiita.com/lyrical_logical/items/be0140e87c31aeb65e53",
      "http://qiita.com/xoyo24/items/1d6d748cd4641ceadf56",
      "http://qiita.com/rkyymmt@github/items/8306ea722cf6e137d999",
      "http://tototoshi.hatenablog.com/entry/2015/12/23/154104",
      "http://d.hatena.ne.jp/xuwei/20151213/1449977206",
      "http://qtamaki.hatenablog.com/entry/2015/12/14/160153",
      "http://qiita.com/lyrical_logical/items/5aff6d0b8f9dbc571710",
      "http://www.shigemk2.com/entry/my_scala_information",
      "http://qiita.com/momotas210/items/16cf20e9e2b8ab8dd372",
      "http://qiita.com/ponkotuy/items/9561f946652c25e94c62",
      "http://qiita.com/wgag/items/213274f3cb2a064ec91e",
      "http://qiita.com/takashabe/items/12dc169fe192ac809c13",
      "http://qiita.com/ocadaruma/items/28cbfa3fda3681bc2550",
      "http://qiita.com/petitviolet/items/b024fa27a32c0b69386b",
      "http://qiita.com/yohei1126@github/items/d60c6e498bc57c07b880",
      "http://qiita.com/halcat0x15a/items/7fa75de932977b7aa7cc",
      "http://larchitecture.blogspot.jp/2015/12/scala-jira.html"
      ],

    "title": ["Scala Advent Calendar 2015"]
  },
  ...
]

他にも参考にさせていただいたサイト
dragstar.hatenablog.com