1. 程式人生 > >Scrapy入門教程(一)

Scrapy入門教程(一)

既然你點進來看了,我就預設你知道什麼是爬蟲了。不知道也沒有關係,來看一下爬蟲的定義:網路爬蟲,是一種按照一定的規則,自動地抓取全球資訊網資訊的程式或者指令碼。可以寫爬蟲的語言、框架有很多,這裡記錄一下Scrapy的入門教程。

一、為什麼要選擇Scrapy?

  • Scrapy有名氣,只要你做過爬蟲就基本上都聽說過Scrapy
  • Scrapy有完備的文件,想自己檢視文件的 點選這裡
  • Scrapy是一個框架,基本上把你爬取資料及之後處理的一些操作都整合到了一起,節省你編寫指令碼的時間

二、安裝

安裝Scrapy需要在Python2.7 或Python3.4 及以上版本,可以通過pip或Anaconda、Miniconda安裝

如果你使用pip安裝,可以在powershell/cmd/bash中鍵入

pip install scrapy

如果你使用Anaconda或者Miniconda,可以鍵入

conda install -c conda-forge scrapy

PS:在安裝過程中你可能遇到Twisted這個包安裝報錯,你可以開啟這裡找到你適合你機器環境的版本的whl包並執行下列命令先安裝Twisted,然後再安裝Scrapy就可以了。

pip install D:\Twisted‑18.9.0‑cp37‑cp37m‑win_amd64.whl

感謝加州大學爾灣分校熒光動力學實驗室的Christoph Gohlke

 

安裝完了之後鍵入

scrapy -V

如果出現下圖畫面即為安裝成功

 

三、試一試

這裡我用了PyCharm,不用也沒關係,只用命令列和記事本也是可以的。

在Terminal這個標籤頁裡(poweshell/cmd/bash也可以,注意先要轉到你要建立專案的目錄再執行命令)鍵入

scrapy startproject tutorial

 這裡tutorial是你的專案名稱,你可以根據你的爬蟲內容自行更改。

專案建立好了之後結構如下:

 
接下來我們按照命令列裡的提示轉到爬蟲目錄使用模板生成我們第一個爬蟲,鍵入如下命令:

cd tutorial\tutorial\spiders
scrapy genspider quotes quotes.toscrapy.com

 這裡quotes是你爬蟲的名稱,注意這個名稱必須是專案裡唯一的(即其他爬蟲不能使用同樣的名字,否則會報錯) quotes.toscrapy.com是你要爬取資料的網站的域名

執行完命令之後會在spiders這個資料夾裡出現quotes.py這個檔案,這就是我們第一個爬蟲

這裡引入了scrapy包,建立了一個QuotesSpider類繼承了scrapy.Spider類,QuotesSpider類的name就是上面提到的必須唯一的爬蟲名稱,allowed_domains表示爬蟲只爬取這個數組裡記載的域名的網頁,start_urls是爬蟲開始爬取資料的url(如果使用了start_urls,則會把response自動交給parse函式處理)

接下來我們改造一下爬蟲,把爬取的網頁儲存下來。quotes.toscrapy.com這個網站是Scrapy官方建立的給大家練習爬取資料的網站沒有連結到其他網站,allowed_domains可以先刪掉,但要保留start_urls陣列 或者start_requests函式以及解析response的解析函式。

start_urls陣列和parse函式與start_requests函式和parse函式是等價的,它們區別是如果你使用了start_urls陣列就只能使用parse函式解析response,如果使用了start_requests函式可以指定回撥的解析函式不一定是parse函式也可以是parseXXX,start_urls是start_requests的一個簡寫。

# -*- coding: utf-8 -*-
import scrapy


class QuotesSpider(scrapy.Spider):
    name = 'quotes'
    def start_requests(self):
        urls = [
            'http://quotes.toscrape.com/page/1/',
            'http://quotes.toscrape.com/page/2/',
        ]
        for url in urls:
            yield scrapy.Request(url=url, callback=self.parse)

    def parse(self, response):
        page = response.url.split("/")[-2]
        filename = 'quotes-%s.html' % page
        with open(filename, 'wb') as f:
            f.write(response.body)
        self.log('Saved file %s' % filename)

執行一下

scrapy crawl quotes

會在執行命令的目錄下得到兩個html檔案,這樣我們第一個簡單的爬蟲就完成了,它成功的儲存了兩個html檔案。

但是實際工作中我們是不會滿足於只儲存網頁的,我們要把網頁裡有用的資料儲存下來,這就需要我們對網頁內容也就是html進行解析,Scrapy給我們提供了一個命令列的方式獲取html

scrapy shell "http://quotes.toscrapy.com/page/1"

 通過命令列獲得網頁的html程式碼後我們就可以對html進行解析了,Scrapy提供了css選擇器解析和XPath解析兩種方法,當然也可以結合beautifulsoup lxml等進行解析,如果有興趣可以自學。

如果實在是懶的話可以在chrome中開啟網頁按F12 然後按Crtl+Shift+C用滑鼠選擇你想選擇的元素在Elements標籤頁中右鍵點選然後Copy->Copy selector 或者copy XPath

鍵入

response.css('title')

如果沒有意外的話會返回

[<Selector xpath='descendant-or-self::title' data='<title>Quotes to Scrape</title>'>]

鍵入

response.css('title::text').extract_first()

會把html標籤去掉直接返回title的內容Quotes to Scrapy

接下來我們再來把爬蟲改一改使用css選擇器將text欄位,author欄位,tag欄位提取出來,然後注意到這個網頁的右下角有下一頁的連結,我們可以把下一頁的連結也提取出來繼續請求並解析。

# -*- coding: utf-8 -*-
import scrapy


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

    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(),
            }

        next_page = response.css('li.next a::attr(href)').extract_first()
        if next_page is not None:
            next_page = response.urljoin(next_page)
            yield scrapy.Request(next_page, callback=self.parse)

鍵入

scrapy crawl quotes -o quotes.json

添加了-o 引數將解析好的資料生成到quotes.json檔案中。Scrapy可以很方便的將資料生成到json/csv/jl(json line) 檔案中。

 

好了,到這裡基本上你就算是入門了。

四、對Scrapy的理解

上圖是網上廣為流傳的一張Scrapy的原理圖,簡單說一下吧一切的開始是從spider(爬蟲)開始的。

  1. Spider將要爬取的url傳給Scheduler處理
  2. Scheduler將url安排Downloader訪問全球資訊網並獲得response(響應)
  3. Downloader將response交回給spider解析
  4. Spider解析後將資料交給Item和Pipeline進行後續處理

**************************

 最後如果你願意的話,請隨意打賞。