Help us understand the problem. What is going on with this article?

Scrapy入門(1)

More than 3 years have passed since last update.

Scrapy入門(1)

はじめに

PythonでWebスクレイピングを行う場合には、様々なアプローチが存在します。この記事ではスクレイピング用のフレームワークであるScrapyを題材に取り上げ実際に簡単なサンプルを作成しながら、Scrapyについて学んでいきます。

Scrapyとは

Scarpyとは速くて、ハイレベルなスクレイピングのフレームワークです。Webサイトのクロールと、スクレイピングに関する様々な機能を持っています。主要な機能はコンポーネントに分かれており、ユーザーは各コンポーネントに関連するクラスなどを作成して、プログラムを作っていきます。

コンポーネント図
http://doc.scrapy.org/en/1.0/topics/architecture.html より

主要なコンポーネントは次の通りです。

Scrapy Engine

  • コンポーネント間のデータフローの制御を担当
  • 特定のアクションが発生したら、イベントを発生

Scheduler

  • Engineからリクエストを受け取り、キューイングとスケジューリングを担当

Downloader

  • 実際のダウンロード処理を担当
  • Download middlewareで処理を差し込む事が可能

Spiders

  • ユーザーが作成するカスタムクラス
  • 取得したいURL、抽出したい部分を記述する
  • ダウンロードしたコンテンツをスクレイピングして、Itemを作成

Item Pipeline

  • スパイダーによって抽出されたアイテムの出力処理
  • データのクレンジング、検証
  • 永続化(JSON、File、DB、Mail)

このようにScrapyには様々な機能があります。今回はまずScrapyの基本概念であるSpiderを作成して、
Qiita上にあるAdventCalendarに投稿されているURLを取得するプログラムを書いてみます。

インストール

まずはpipにてインストールします。

pip install scrapy

Spiderの作成

次にコンポーネントの一つであるSpiderを作成します。
Spiderにはクロールの処理を開始するためのURLのエンドポイントと、
URLの抽出するための処理を記述します。

# -*- 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,
        }

実行

Scrapyにはたくさんのコマンドが付属しています。今回はSpiderを実行するための
runspiderコマンドを使用して、Spiderを実行します。
-oオプションを使用するとparse_itemで作成した結果を、JSON形式でファイルに保存する事が出来ます。

scrapy runspider qiita_spider.py -o advent_calendar.json

結果

実行結果は次の通りです。
各アドベントカレンダーのタイトルと投稿されたURLの一覧を取得することができました!

{
    "urls": [
      "http://loboskobayashi.github.io/pythonsf/2015/12-01/recomending_PythonSf_one-liners_for_general_python_codes/",
      "http://qiita.com/csakatoku/items/444db2d0e421265ec106",
      "http://qiita.com/csakatoku/items/86904adaa0922e80069c",
      "http://qiita.com/Hironsan/items/fb6ee6b8e0291a7e5a1d",
      "http://qiita.com/csakatoku/items/77a36888d0851f6d4ff0",
      "http://qiita.com/csakatoku/items/a5b6c3604c0d411154fa",
      "http://qiita.com/sharow/items/21e421a2a40275ee9bb8",
      "http://qiita.com/Lspeciosum/items/d248b64d1bdcb8e39d32",
      "http://qiita.com/CS_Toku/items/353fd4b0fd9ed17dc152",
      "http://hideharaaws.hatenablog.com/entry/django-upgrade-16to18",
      "http://qiita.com/FGtatsuro/items/0efebb9b58374d16c5f0",
      "http://shinyorke.hatenablog.com/entry/2015/12/12/143121",
      "http://qiita.com/wrist/items/5759f894303e4364ebfd",
      "http://qiita.com/kimihiro_n/items/86e0a9e619720e57ecd8",
      "http://qiita.com/satoshi03/items/ae616dc080d085604b06",
      "http://qiita.com/CS_Toku/items/32028e65a8bfa97266d6",
      "http://fx-kirin.com/python/nfp-linear-reggression-model/"
    ],
    "title": [
      "Python \u305d\u306e2 Advent Calendar 2015"
    ]
  },
  {
    "urls": [
      "http://qiita.com/nasa9084/items/40f223b5b44f13ef2925",
      "http://studio3104.hatenablog.com/entry/2015/12/02/120957",
      "http://qiita.com/Tsutomu-KKE@github/items/29414e2d4f30b2bc94ae",
      "http://qiita.com/icoxfog417/items/913bb815d8d419148c33",
      "http://qiita.com/sakamotomsh/items/ab6c15b971587905ef43",
      "http://cocu.hatenablog.com/entry/2015/12/06/022100",
      "http://qiita.com/masashi127/items/ca092c13e1300f4f6ade",
      "http://qiita.com/kaneshin/items/269bc5f156d86f8a91c4",
      "http://qiita.com/wh11e7rue/items/15603e8970c36ab9733d",
      "http://qiita.com/ohkawa/items/368e6bcadc56a118adaf",
      "http://qiita.com/teitei_tk/items/5c5c9e653b3a13108d12",
      "http://sinhrks.hatenablog.com/entry/2015/12/13/215858"
    ],
    "title": [
      "Python Advent Calendar 2015"
    ]
  },

終わりに

今回はScrapyの基本的なコンポーネントである、Spiderを作成してスクレインピングを行いました。
Scrapyを使用すると、クローリングに関する定型的な処理はフレームワーク側で処理を担当してくれます。そのため開発者はURLの抽出処理や、データの保存処理などサービスやアプリケーションに本当に必要な部分のみを記述して開発することができます。次回以降はキャッシュや保存処理などについて取り上げます。お楽しみに!

Scrapy入門(2)

checkpoint
Python
squeeze-inc
「価値の詰まった社会を創る」をビジョンに掲げ、民泊・宿泊チャネルの全物件情報・予約情報・顧客情報を一元管理できる『suitebook』を運営しています。
https://squeeze-inc.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした