LoginSignup
22
18

More than 5 years have passed since last update.

Scrapy入門(3)

はじめに

Scrapy入門(1)
Scrapy入門(2)

前回までの記事では、Scrapyを利用してWebAPIをコールする方法を試しました。今回はファイルのダウンロード処理を行うSpiderを作成してみましょう。

Spiderの作成

今回はMLBに関するデータ(zipファイル)をダウンロードするSpiderを作成します。実際のデータはSean Lahman Databaseで公開されているデータを利用します。ダウンロードしたzipファイルは任意のディレクトリに保存することにしましょう。

Spriderの処理の流れは次の通りです。

  • start_urlsのページの内容を取得
  • 取得したページの内容を解析し、aタグのhrefにcsvの文字列が含まれているurlを取得
  • 上記で取得したurlの内容を取得
get_csv_spider.py
# -*- coding:utf-8 -*-

from scrapy import Spider
from scrapy.http import Request


class GetCSVSpider(Spider):
    name = 'get_csv_spider'
    allowed_domains = ['seanlahman.com']

    custom_settings = {
        'DOWNLOAD_DELAY': 1.5,
    }

    # CSVファイルを保存する任意のディレクトリ
    DIR_NAME = '/tmp/csv/'

    # エンドポイント(クローリングを開始するURLを記載する)
    start_urls = ['http://seanlahman.com/baseball-archive/statistics/']

    # URLの抽出処理を記載
    def parse(self, response):
        for href in response.css('.entry-content a[href*=csv]::attr(href)'):
            full_url = response.urljoin(href.extract())

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

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

        file_name = '{0}{1}'.format(self.DIR_NAME, response.url.split('/')[-1])

        # ファイルの保存
        f = open(file_name, 'w')
        f.write(response.body)
        f.close()

実行

Scrapy付属のコマンドを利用してクロールを実行します。

scrapy runspider get_csv_spider

コマンドを実行すると下記のようなログがコンソールに表示されます。ログには取得中のURL、ステータス、バイト数、サマリーなど有益な情報が表示されます。

2016-12-06 10:02:22 [scrapy] INFO: Scrapy 1.2.0 started (bot: scrapybot)
2016-12-06 10:02:22 [scrapy] INFO: Overridden settings: {'TELNETCONSOLE_ENABLED': False, 'SPIDER_MODULES': ['crawler.main.spiders'], 'COOKIES_ENABLED': False, 'DOWNLOAD_DELAY': 1}
2016-12-06 10:02:22 [scrapy] INFO: Enabled extensions:
['scrapy.extensions.logstats.LogStats',
 'scrapy.extensions.corestats.CoreStats']
2016-12-06 10:02:22 [scrapy] INFO: Enabled downloader middlewares:
['scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware',
 'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware',
 'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware',
 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware',
 'scrapy.downloadermiddlewares.retry.RetryMiddleware',
 'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware',
 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware',
 'scrapy.downloadermiddlewares.redirect.RedirectMiddleware',
 'scrapy.downloadermiddlewares.chunked.ChunkedTransferMiddleware',
 'scrapy.downloadermiddlewares.stats.DownloaderStats']
2016-12-06 10:02:22 [scrapy] INFO: Enabled spider middlewares:
['scrapy.spidermiddlewares.httperror.HttpErrorMiddleware',
 'scrapy.spidermiddlewares.offsite.OffsiteMiddleware',
 'scrapy.spidermiddlewares.referer.RefererMiddleware',
 'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware',
 'scrapy.spidermiddlewares.depth.DepthMiddleware']
2016-12-06 10:02:22 [scrapy] INFO: Enabled item pipelines:
[]
2016-12-06 10:02:22 [scrapy] INFO: Spider opened
2016-12-06 10:02:22 [scrapy] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2016-12-06 10:02:23 [scrapy] DEBUG: Crawled (200) <GET http://seanlahman.com/baseball-archive/statistics/> (referer: None)
2016-12-06 10:02:28 [scrapy] DEBUG: Crawled (200) <GET http://seanlahman.com/files/database/lahman30_csv.zip> (referer: http://seanlahman.com/baseball-archive/statistics/)
2016-12-06 10:02:35 [scrapy] DEBUG: Crawled (200) <GET http://seanlahman.com/files/database/lahman51-csv.zip> (referer: http://seanlahman.com/baseball-archive/statistics/)
2016-12-06 10:02:38 [scrapy] DEBUG: Crawled (200) <GET http://seanlahman.com/files/database/lahman_50-csv.zip> (referer: http://seanlahman.com/baseball-archive/statistics/)
2016-12-06 10:02:39 [scrapy] DEBUG: Crawled (200) <GET http://seanlahman.com/files/database/lahman53_csv.zip> (referer: http://seanlahman.com/baseball-archive/statistics/)
2016-12-06 10:02:41 [scrapy] DEBUG: Crawled (200) <GET http://seanlahman.com/files/database/lahman56-csv.zip> (referer: http://seanlahman.com/baseball-archive/statistics/)
2016-12-06 10:02:41 [scrapy] DEBUG: Crawled (200) <GET http://seanlahman.com/files/database/lahman52_csv.zip> (referer: http://seanlahman.com/baseball-archive/statistics/)
2016-12-06 10:02:42 [scrapy] DEBUG: Crawled (200) <GET http://seanlahman.com/files/database/lahman54_csv.zip> (referer: http://seanlahman.com/baseball-archive/statistics/)
2016-12-06 10:02:47 [scrapy] DEBUG: Crawled (200) <GET http://seanlahman.com/files/database/lahman591-csv.zip> (referer: http://seanlahman.com/baseball-archive/statistics/)
2016-12-06 10:02:49 [scrapy] DEBUG: Crawled (200) <GET http://seanlahman.com/files/database/lahman55_csv.zip> (referer: http://seanlahman.com/baseball-archive/statistics/)
2016-12-06 10:02:49 [scrapy] DEBUG: Crawled (200) <GET http://seanlahman.com/files/database/lahman57-csv.zip> (referer: http://seanlahman.com/baseball-archive/statistics/)
2016-12-06 10:02:52 [scrapy] DEBUG: Crawled (200) <GET http://seanlahman.com/files/database/lahman58-csv.zip> (referer: http://seanlahman.com/baseball-archive/statistics/)
2016-12-06 10:02:55 [scrapy] DEBUG: Crawled (200) <GET http://seanlahman.com/files/database/lahman-csv_2014-02-14.zip> (referer: http://seanlahman.com/baseball-archive/statistics/)
2016-12-06 10:02:55 [scrapy] DEBUG: Crawled (200) <GET http://seanlahman.com/files/database/lahman-csv_2015-01-24.zip> (referer: http://seanlahman.com/baseball-archive/statistics/)
2016-12-06 10:03:00 [scrapy] DEBUG: Crawled (200) <GET http://seanlahman.com/files/database/lahman2012-csv.zip> (referer: http://seanlahman.com/baseball-archive/statistics/)
2016-12-06 10:03:00 [scrapy] INFO: Closing spider (finished)
2016-12-06 10:03:00 [scrapy] INFO: Dumping Scrapy stats:
{'downloader/request_bytes': 4518,
 'downloader/request_count': 15,
 'downloader/request_method_count/GET': 15,
 'downloader/response_bytes': 104279737,
 'downloader/response_count': 15,
 'downloader/response_status_count/200': 15,
 'finish_reason': 'finished',
 'finish_time': datetime.datetime(2016, 12, 6, 1, 3, 0, 285944),
 'log_count/DEBUG': 15,
 'log_count/INFO': 7,
 'request_depth_max': 1,
 'response_received_count': 15,
 'scheduler/dequeued': 15,
 'scheduler/dequeued/memory': 15,
 'scheduler/enqueued': 15,
 'scheduler/enqueued/memory': 15,
 'start_time': datetime.datetime(2016, 12, 6, 1, 2, 22, 878024)}
2016-12-06 10:03:00 [scrapy] INFO: Spider closed (finished)

ダウンロードが完了したので実際にダウンロードされているか確認しましょう。
無事ダウンロードされているようですね。

tree /tmp/csv
/tmp/csv
├── lahman-csv_2014-02-14.zip
├── lahman-csv_2015-01-24.zip
├── lahman2012-csv.zip
├── lahman30_csv.zip
├── lahman51-csv.zip
├── lahman52_csv.zip
├── lahman53_csv.zip
├── lahman54_csv.zip
├── lahman55_csv.zip
├── lahman56-csv.zip
├── lahman57-csv.zip
├── lahman58-csv.zip
├── lahman591-csv.zip
└── lahman_50-csv.zip

0 directories, 14 files

終わりに

Scrapyを使用すると、ファイルのダウンロード処理も簡単に記述することができます。Scrapyはクローリング用のフレームワークなので、開発者はフレームワークから呼び出される部分にのみ集中して開発することが可能です。次回以降は今回説明しなかった、データのパイプライン処理について取り上げます。お楽しみに!

参考URL

22
18
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
22
18