scrapy框架簡介和基礎應用

1、Scrapy介紹

一、Scrapy是什麼

  Scrapy 是一個開源和協做的框架,其最初是爲了頁面抓取 (更確切來講, 網絡抓取 )所設計的,使用它能夠以快速、簡單、可擴展的方式從網站中提取所需的數據。但目前Scrapy的用途十分普遍,可用於如數據挖掘、監測和自動化測試等領域,也能夠應用在獲取API所返回的數據(例如 Amazon Associates Web Services ) 或者通用的網絡爬蟲。html

二、何謂框架

  所謂框架其實就是一個已經被集成了各類功能(高性能異步下載,隊列,分佈式,解析,持久化等)的具備很強通用性的項目模板。對於框架的學習,重點是要學習其框架的特性、各個功能的用法便可。
  scrapy和requests、bs4的關係,能夠作以下類比:python

requests + bs4 => socket
scrapy框架 => djangolinux

  Scrapy 是基於twisted框架開發而來,twisted是一個流行的事件驅動的python網絡框架。所以Scrapy使用了一種非阻塞(又名異步)的代碼來實現併發(基於Twisted實現單線程併發下載頁面)。也具有解析下載內容功能、幫助實現「遞歸」、幫助完成數據持久化(數據寫入硬盤或數據庫)、還具有一些擴展性功能(自定義組件)。web

2、Scrapy核心組件

一、五大組件介紹

  • 引擎(Scrapy)
    用來處理整個系統的數據流處理, 觸發事務(框架核心)
  • 管道(Pipeline)
    負責處理爬蟲從網頁中抽取的實體,主要的功能是持久化實體、驗證明體的有效性、清除不須要的信息。當頁面被爬蟲解析後,將被髮送到項目管道,並通過幾個特定的次序處理數據。
  • 調度器(Scheduler)
    用來接受引擎發過來的請求, 壓入隊列中, 並在引擎再次請求的時候返回. 能夠想像成一個URL(抓取網頁的網址或者說是連接)的優先隊列, 由它來決定下一個要抓取的網址是什麼, 同時去除重複的網址
  • 下載器(Downloader)
    用於下載網頁內容, 並將網頁內容返回給蜘蛛(Scrapy下載器是創建在twisted這個高效的異步模型上的)
  • 爬蟲文件(Spiders)
    爬蟲是主要幹活的, 用於從特定的網頁中提取本身須要的信息, 即所謂的實體(Item)。用戶也能夠從中提取出連接,讓Scrapy繼續抓取下一個頁面

二、五大核心組件工做流程

五大核心組件

  引擎首先會將爬蟲文件中的起始url獲取,並提交到調度器中。若是須要從url中下載數據,則調度器會將url經過引擎提交給下載器,下載器根據url去下載指定內容(響應器)。下載好的數據會經過引擎移交給爬蟲文件,爬蟲文件能夠將下載的數據進行指定格式的解析。若是解析出的數據須要進行持久化存儲,則爬蟲文件會將解析好的數據經過引擎移交給管道進行持久化存儲。數據庫

3、Scrapy安裝

一、Windows平臺

一、安裝wheel
    pip3 install wheel   # 安裝後,便支持經過wheel文件安裝軟件,wheel文件官網:https://www.lfd.uci.edu/~gohlke/pythonlibs
二、下載twisted(Scrapy基於twisted框架):
    http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted
    安裝twisted:
    進入下載目錄,執行: 
    pip3 install Twisted‑17.1.0‑cp35‑cp35m‑win_amd64.whl
三、下載並安裝pywin32:    
    pip3 install pywin32
四、安裝scrapy
    pip3 install scrapy

二、Linux平臺

pip3 install scrapy

4、Scrapy基礎使用

一、使用流程

(1)建立一個工程

  切換到項目目錄後,執行建立項目的命令,爬蟲項目即建立成功。django

$ scrapy startproject firstPro(工程名稱)
  • 目錄結構
      用pycharm打開建立的工程,能夠看到以下目錄結構。
project_name/
|--scrapy.cfg                # 項目的主配置信息。(真正爬蟲相關的配置信息在settings.py文件中)
|--project_name/
    |--__init__.py
    |--items.py               # 設置數據存儲模板,用於結構化數據,如Django的Model
    |--pipelines.py           # 數據持久化處理
    |--settings.py            # 配置文件(通常修改這裏),如:遞歸的層數、併發數,延遲下載等
    |--spiders/               # 爬蟲目錄,如:建立文件,編寫爬蟲解析規則
         |--__init__.py

(2)建立爬蟲應用程序

$ pwd
/Users/hqs/ScrapyProjects/firstBlood
$ scrapy genspider qiubai www.qiushibaike.com
Created spider 'qiubai' using template 'basic' in module:
  firstBlood.spiders.qiubai

  執行成功後,就能夠在項目的spiders目錄下找到新生成的爬蟲文件了。windows

  1)建立爬蟲程序語法瀏覽器

scrapy genspider 應用名稱 爬取網頁的起始url

  2)建立的爬蟲文件內容模板bash

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

class QiubaiSpider(scrapy.Spider):  # Spider是全部爬蟲的父類
    name = 'qiubai'   # 爬蟲文件的名稱:經過爬蟲文件的名稱能夠指定定位到某一個具體的爬蟲文件
    allowed_domains = ['www.qiushibaike.com']   # 容許的域名:只爬取指定域名下的頁面數據
    start_urls = ['http://www.qiushibaike.com/']   # 起始url:當前工程將要爬取頁面對應的url

    def parse(self, response):
        """
        解析方法:對獲取的頁面數據進行指定內容解析
        :param response: 根據起始url列表發起請求,請求成功返回的響應對象
        :return:
        """
        pass

(3)編寫爬蟲文件

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


class QiubaiSpider(scrapy.Spider):  # Spider是全部爬蟲的父類
    name = 'qiubai'   # 爬蟲文件的名稱:經過爬蟲文件的名稱能夠指定定位到某一個具體的爬蟲文件
    allowed_domains = ['www.qiushibaike.com']   # 容許的域名:只爬取指定域名下的頁面數據
    start_urls = ['http://www.qiushibaike.com/']   # 起始url:當前工程將要爬取頁面對應的url

    def parse(self, response):
        """
        解析方法:對獲取的頁面數據進行指定內容解析
        :param response: 根據起始url列表發起請求,請求成功返回的響應對象
        :return:
        """
        print(response.text)  # 獲取字符串類型的響應內容
        # print(response.body)  # 獲取字節類型的相應內容

        # 注意:parse方法的返回值必須是迭代器或空
        # 未指定返回值時,返回值默認爲空

(4)修改settings.py配置文件

# Crawl responsibly by identifying yourself (and your website) on the user-agent
USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36' # 假裝請求載體身份

# Obey robots.txt rules
ROBOTSTXT_OBEY = False   # 不聽從門戶網站robots協議,避免某些信息爬取不到

注意:
  (1)取消USER_AGENT註釋,這裏給它添加火狐瀏覽器身份標識,以假裝請求載體身份
  (2)將ROBOTSTXT_BOE修改成False,即不遵照門戶網站的robots協議,避免某些信息爬取不到。(這個可視狀況決定是否遵照)網絡

(5)執行爬蟲程序:

# scrapy crawl  應用名稱 --nolog(阻止日誌信息輸出)
$ scrapy crawl qiubai

  添加 '--nolog' 參數能夠阻止日誌信息的輸出,只輸出爬取的頁面數據。

二、指定頁面數據解析操做示例

  需求:糗百中段子的內容和做者。
  依然使用以前建立的項目,所以省略流程第一步的工程建立操做。

(1)建立爬蟲文件(第二步)

$ pwd
/Users/hqs/ScrapyProjects/firstBlood
$ scrapy genspider qiubaipro www.qiushibaike.com/text
Created spider 'qiubaipro' using template 'basic' in module:
  firstBlood.spiders.qiubaipro

(2)xpath指定內容解析

  Scrapy已經集成好了xpath解析的接口,所以推薦使用xpath進行指定內容的解析。
  Control-Shift-X開啓xpath插件。

xpath解析

(3)編寫代碼(第三步)

import scrapy

class QiubaiproSpider(scrapy.Spider):
    name = 'qiubaipro'
    # allowed_domains = ['www.qiushibaike.com/text']  # 圖片等信息可能不屬於指定域名之下
    start_urls = ['https://www.qiushibaike.com/text/']  # 注意修改默認協議頭

    def parse(self, response):
        # 建議使用xpath來執行指定內容的解析(Scrapy已經集成好了xpath解析的接口)
        # 段子的內容和做者
        div_list = response.xpath('//div[@id="content-left"]/div')
        for div in div_list:
            # 經過xpath解析到的指定內容被存儲到了selector對象中
            # 須要經過extract()方法來提取selector對象中存儲的數據值
            # 方法一:
            # author = div.xpath('./div/a[2]/h2/text()').extract()[0]  # './'表示解析當前局部div; a[2]表示第二個a標籤
            # 方法二:extract_first()等同於extract()[0]
            author = div.xpath('./div/a[2]/h2/text()').extract_first()
            content = div.xpath('.//div[@class="content"]/span/text()').extract_first()  # './/'表示當前局部全部元素;@class匹配類屬性

            print(author)

注意:
  1)第四步的修改配置文件也省略,配置方法見前面一節。
  2)xpath解析的指定內容被存儲到了selector對象中。
  3)能夠經過extract()方法來提取selector對象中存儲的數據值。
  4)selector對象和extract方法

使用extract()方法前:
[<Selector xpath='./div/a[2]/h2/text()' data='\n南九\n'>]
[<Selector xpath='./div/a[2]/h2/text()' data='\n無書齋主\n'>]
[<Selector xpath='./div/a[2]/h2/text()' data='\n請閉上眼睛裏\n'>]

使用extract()方法後:
['\n好吃的焦糖餅乾~\n']
['\n艾瑪*^o^*ZW…\n']
['\n嘻嘻嘻,一\n']

  5)extract_first()等同於extract()[0]

(4)執行代碼(第五步)

# scrapy crawl 爬蟲名稱 :該種執行形式會顯示執行的日誌信息
# scrapy crawl 爬蟲名稱 --nolog:該種執行形式不會顯示執行的日誌信息
$ scrapy crawl qiubaipro --nolog

5、更多文檔參考

Scrapy 0.25 文檔
wupeiqi的Scrapy
爬蟲框架:scrapy

相關文章
相關標籤/搜索