Scrapy入門-第一個爬蟲專案

blue_zy發表於2018-07-23

前言

千辛萬苦安裝完Scrapy,當然要馬上體驗一下啦。詳見:Mac安裝Scrapy及踩坑經驗

本文采用循序漸進的方式,一步步寫出一個完整的爬蟲,包括

  • 使用Scrapy建立專案
  • 使用Scrapy爬取整個網頁
  • 使用Scrapy爬取所需元素
  • 使用Scrapy儲存資料到json檔案

相當於Scrapy入門教程中的基礎篇,如果希望學習Scrapy這個強大的爬蟲框架,只要懂一點點Python語法,可以跟著一起來動手了。

建立專案

只需一行命令即可建立名為 tutorial 的Scrapy專案:

scrapy startproject tutorial

然後 cd tutorial 進入專案目錄,通過 tree tutorial 命令看一下整個專案的結構

tutorial/
    scrapy.cfg            # deploy configuration file
    tutorial/             # project's Python module, you'll import your code from here
        __init__.py
        items.py          # project items definition file
        middlewares.py    # project middlewares file
        pipelines.py      # project pipelines file
        settings.py       # project settings file
        spiders/          # a directory where you'll later put your spiders
            __init__.py

OK,這是建立專案的第一步,然後我們再通過

cd /tutorial
scrapy genspider QuoteSpider

建立爬蟲的模板檔案,QuoteSpider就是檔名,在當前目錄下生成一個QuoteSpider.py檔案

然後我們通過PyCharm開啟這個 tutorial 專案

專案結構圖:
這裡寫圖片描述

QuoteSpider.py 我們開始編寫爬蟲程式碼,其他幾個檔案都有自己的作用,但是本文暫時不需要用到,所以就不介紹了。有需要的童鞋可以參考知乎的這篇文章:Scrapy爬蟲框架教程(一)– Scrapy入門

爬取整個網頁

修改QuotesSpider.py檔案

import scrapy

class QuotesSpider(scrapy.Spider):
    name = "quotes"
    start_urls = [
        'http://quotes.toscrape.com/page/1/',
        'http://quotes.toscrape.com/page/2/',
    ]

    def parse(self, response):
        page = response.url.split("/")[-2]
        filename = 'quotes-%s.html' % page
        with open(filename, 'wb') as f:
            f.write(response.body)
  • name 是爬蟲的名字,作為唯一標識不可重複
  • parse() 方法進行頁面解析,我們這裡直接儲存為html檔案

寫完程式碼,怎麼開始執行呢?

終端輸入:

scrapy crawl quotes

就能看到當前目錄下多了兩個html檔案:
這裡寫圖片描述

這就完成了我們最最簡單的一個爬蟲了,總結一下:

  1. scrapy startproject name 建立專案
  2. scrapy genspider spider_name 建立爬蟲檔案
  3. 編寫程式碼
  4. scrapy crawl spider_name 執行爬蟲

提取所需元素

通過爬取整頁,我們掌握了最基本的爬蟲,但是實際上,通常我們需要的只是網頁中一部分對我們有用的資訊,那麼就涉及到了元素的過濾和篩選。在Scrapy中,我們可以通過 shell 來獲取網頁元素。

舉個例子:

scrapy shell 'http://quotes.toscrape.com/page/1/'

你會看到以下資訊:

2018-07-22 23:59:05 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://quotes.toscrape.com/page/1/> (referer: None)
[s] Available Scrapy objects:
[s]   scrapy     scrapy module (contains scrapy.Request, scrapy.Selector, etc)
[s]   crawler    <scrapy.crawler.Crawler object at 0x103186400>
[s]   item       {}
[s]   request    <GET http://quotes.toscrape.com/page/1/>
[s]   response   <200 http://quotes.toscrape.com/page/1/>
[s]   settings   <scrapy.settings.Settings object at 0x10400f7f0>
[s]   spider     <DefaultSpider 'default' at 0x1042f6dd8>
[s] Useful shortcuts:
[s]   fetch(url[, redirect=True]) Fetch URL and update local objects (by default, redirects are followed)
[s]   fetch(req)                  Fetch a scrapy.Request and update local objects 
[s]   shelp()           Shell help (print this help)
[s]   view(response)    View response in a browser
>>> 

在這裡,我們再通過css選擇器來選擇所需的元素。例如:

>>> response.css('title::text').extract_first()
'Quotes to Scrape'
  • title:網頁中的標籤,也就是我們所需要的元素
  • extrac_first() :相當於返回title中的第一個值,因為css返回的是一個列表
    做個試驗,我們這樣寫 response.css(‘title::text’).extract()
    輸出結果為:[‘Quotes to Scrape’],說明返回值就是一個列表

其他所有元素都能通過這個方式來得到,因此接下來我們通過一個完整的例子來實踐一下。

獲取所需元素並存到json檔案

目標:獲取網頁的text,author,tags元素,並儲存下來

步驟1:獲取所需的元素(通過CSS)
        for quote in response.css('div.quote'):
            yield {
                'text': quote.css('span.text::text').extract_first(),
                'author': quote.css('small.author::text').extract_first(),
                'tags': quote.css('div.tags a.tag::text').extract(),
            }

這些標籤我們可以從html檔案中通過檢視原始碼得到他們的層級關係

步驟2:完整的QuotesSpider.py程式碼
import scrapy


class QuotesSpider(scrapy.Spider):
    name = "quotes"
    start_urls = [
        'http://quotes.toscrape.com/page/1/',
        'http://quotes.toscrape.com/page/2/',
    ]

    def parse(self, response):
        for quote in response.css('div.quote'):
            yield {
                'text': quote.css('span.text::text').extract_first(),
                'author': quote.css('small.author::text').extract_first(),
                'tags': quote.css('div.tags a.tag::text').extract(),
            }
步驟3:儲存資料到json檔案

通過以下命令:

scrapy crawl quotes -o quotes.json
  • -o:輸出
  • quotes.json:儲存的json檔名

最終儲存下來的結果:
這裡寫圖片描述

總結

就以上的Demo而言,Scrapy這個爬蟲框架的上手難度算是比較低的,不需要額外的配置,也沒有很複雜的模板,基本達到了開箱即用的效果。而且編寫程式碼的過程中也非常簡單。一邊閱讀官方文件,一邊自己操作,花了晚上2個小時的時間就能做出這樣的效果,個人還是很滿意的(為Scrapy打call~)。至於後面的進階操作,還需要慢慢實踐,不斷踩坑總結。一起努力吧!

相關文章