LoginSignup
14
35

More than 5 years have passed since last update.

Scrapy メモ

Posted at

Webページのスクレイピングと分析・可視化で使用したPython製WebクローラScrapyについて覚えたことについて記載する。
本記事はメモ程度の内容であり、情報の正確性については保証しない。必ず公式ドキュメントを参照すること。

サンプルコード

サンプルコード1

import scrapy

class QiitaCalendarSpider(scrapy.Spider):
    name = "qiita_calendar"
    allowed_domains = ["qiita.com"]
    start_urls = ["http://qiita.com/advent-calendar/2016/calendars"]

    custom_settings = {
        "DOWNLOAD_DELAY": 1,
    }

    def parse(self, response):
        for href in response.css('table.table.adventCalendarList tbody tr'):
            calendar_title = href.css('td.adventCalendarList_calendarTitle a::text').extract_first()
            calendar_url = href.css('td.adventCalendarList_calendarTitle a::attr(href)').extract_first()
            calendar_attendees = href.css(
                'td.adventCalendarList_progress span.adventCalendarList_recruitmentCount::text').extract_first()

            yield {
                'calendar_title': calendar_title,
                'calendar_url': response.urljoin(calendar_url),
                'calendar_attendees': calendar_attendees
            }

            for page in response.css('li.hidden-xs a'):
                next_page = page.css('::attr(href)').extract_first()
                if next_page is not None:
                    next_page = response.urljoin(next_page)
                    yield scrapy.Request(next_page, callback=self.parse)

サンプルコード2

    def start_requests(self):
        qiita_calendars = QiitaCalendarLoader()
        for url in qiita_calendars.urls():
            yield scrapy.Request(url=url, callback=self.parse)

コーディング

DOWNLOAD_DELAYは最初に設定するべき

DOWNLOAD_DELAYはクロール毎のインターバル時間を秒単位で設定するプロパティ。これを設定しないと簡単にWebサイトにDoSアタックをかけることになる。絶対に一番最初に設定すること

allowed_domains

必須ではないものの設定推奨。このリストに含まれるドメインしかクロールしない。

レスポンスの取扱い

parse(self, response)で渡されるresponseで主に使うのはtextcss()urljoin()の3つ。
response.textはhtml情報がテキスト形式で入っているので、このままBeautifulSoupに渡すことができる。
response.css()はCSSセレクタによりhtml内の任意のセクションのSelectorインスタンスのリストを返す。インスタンスに含まれるデータは extract() でアクセス可能。リストのままでも、extract_first()で最初の要素に対してのみextract()をかけることが可能。
response.urljoin(path)は、pathと現在クロールしているURLを合わせてURLのフルパスを返す。

start_urls と start_requests()

最初にクロールするURLの一覧はリストstart_urlsに書く以外に、start_requests()でyieldするという方法がある。(サンプルコード2)
今回の例では、カレンダー一覧ページで取得したカレンダーURLを含むjsonをロードし(QiitaCalendarLoader)、そのURLに対してクロールするという処理を行っている。

コマンド

プロジェクト作成

scrapy startproject <プロジェクト名> で作成可能。

参考: https://doc.scrapy.org/en/1.3/topics/commands.html#genspider

Spider生成

scrapy genspider <スパイダー名> <対象ドメイン>で作成可能だが、大したことはしないので別に使わなくてもいい。

参考: https://doc.scrapy.org/en/1.3/topics/commands.html#genspider

クローリング

scrapy crawl <スパイダー名>

プロジェクトを作成した場合はcrawlコマンドを使う。

参考: https://doc.scrapy.org/en/1.3/topics/commands.html#crawl

インタラクティブシェル

scrapy shell <URL>

ipythonによるインタラクティブシェルモードに入る。URLは省略可。
URLを指定した場合、既に response 変数にレスポンスが格納されている。
インタラクティブシェルモードを起動するとヘルプが表示されるが、特に覚えるべきメソッドは2つ。

shelp()

ヘルプを表示する。

fetch(url)

あらたにURLをクロールする。結果はresponseに格納される。

settings.py

プロジェクトを作成すると、settings.py という設定ファイルが作成される。DOWNLOAD_DELAYなど、全てのスパイダーで共通の設定を行うものはこちらに記述した方がいい。

14
35
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
35