Scrapy爬蟲框架

本文參考傳智播客的Scrapy框架視頻教程
視頻課程鏈接:http://study.163.com/course/courseMain.htm?courseId=1004236002

Scrapy 爬蟲初探

1、概述

  • Scrapy是用純Python實現的一個爲了爬取網站數據、提取結構性數據而編寫的應用框架
  • 用戶只需要定製開發幾個模塊就可以輕鬆的實現一個爬蟲,用來抓取網頁內容以及各種圖片
  • Scrapy 使用了 Twisted 異步網絡框架來處理網絡通電訊,可以加快下載速度;且其中包含了許多中間件接口,可以靈活的完成各種需求(所謂異步網絡框架,就是可以併發很多請求,相當於多線程機制)

2、Scrapy 架構

這裏寫圖片描述

2.1 Scrapy 架構組件

  • Scrapy Engine(引擎),只負責Spider、ItemPipeline、Downloader、Scheduler之間的相互通訊,整個架構中的所有信號都要由引擎發佈
  • Scheduler(調度器),負責調度請求,主要可以實現以下兩個功能:
    • 調度請求:接收引擎發送的所有Request請求,並按照一定方式進行整理排列,入隊,然後依次出隊列,請求就交給下載器進行下載,如圖所示;(在Request請求出隊列時,實際上是調度器先把請求交給引擎,引擎在把接收到的請求交給下載器)
    • 去重:調度器能夠識別重複的請求,不進行重複處理;
  • Downloader(下載器),負責處理引擎發來的請求,並將下載到的Responses響應文件返回給引擎
  • Spider(爬蟲),就是我們自己需要寫的爬蟲文件,處理引擎傳來的Responses響應文件,從中分析提取數據
    • item字段需要的數據:我們自己定製的字段,可以理解爲字典,我們定義了其中的鍵,需要將值存入item字段中,然後將其交給管道文件存儲
    • 需要跟進的URL數據:例如子網頁,將其構建成一個請求,交給引擎,再次調度器
  • Item Pipeline(管道),負責處理從Spider中獲取的item字段,並進行後期處理
  • Downloader Middlewares(下載中間件),引擎和下載器之間的組件,可以自己定製來擴展下載功能,例如在下載之前預先加入代理來處理請求
  • Spider Middlewares(Spider中間件),引擎和Spider之間的組件,用於處理引擎和爬蟲之間的通信(即從引擎傳到Spider的Responses響應文件,從Spider傳到引擎的Request請求),由於大部分工作在Spider中完成,因此很少用到Spider中間件

2.2 Scrapy 運作流程

  1. 引擎首先向Spider詢問想要爬取的網站
  2. Spider中包含了爬蟲需要爬取的URL地址,通過引擎將其交給Scheduler調度器
  3. Scheduler調度器接收到引擎傳來的Request請求進行處理,入隊,並按順序通過引擎將請求發送給下載器
  4. 下載器接收到引擎傳來的請求後,按照自定義的下載中間件設置處理:
    • 將下載成功的Response響應文件通過引擎傳送給Spider;
    • 將下載失敗的Request通過引擎回傳給Scheduler調度器,重新進入請求隊列,等待後續處理;
  5. Spider從引擎傳來的Response響應文件中分析提取數據:
    • 獲取到的Item數據:通過引擎進入管道文件
    • 需要跟進的URL:通過引擎進入Scheduler調度器
  6. Item Pipeline對接收到的Item數據進行後期處理
  7. 停止條件:當Scheduler調度器中的請求隊列爲空,爬蟲結束(對於下載失敗的URL會重新入隊,不會被丟棄)

2.3 Scrapy 框架安裝

Windows系統:

Mac系統:(有Python環境和pip安裝模塊)

1.安裝homebrew(如果有,跳過)

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

2.安裝 wedget(如果有,跳過)

brew install wget

3.安裝 Scrapy

sudo -H pip install Scrapy

Ubuntu操作系統:

2.4 Scrapy 基本命令介紹

Scrapy安裝完成後在命令行輸入scrapy,如果顯示如下,說明Scrapy框架安裝成功
這裏寫圖片描述

上圖中部分命令的解釋和命令調用如下:

Scrapy 1.5.0 - no active project    //Scrapy版本

Usage:
  scrapy <command> [options] [args]  //Scrapy命令調用格式

Available commands:  //可用的命令
  //查看爬蟲性能,例:scrapy bench
  bench         Run quick benchmark test 

  //給出URL地址,然後去下載,例:scrapy fetch "http://www.baidu.com/"
  fetch         Fetch a URL using the Scrapy downloader  

  //創建一個爬蟲,例:scrapy genspyder 爬蟲名 域名
  genspider     Generate new spider using pre-defined templates 

  //啓動一個爬蟲,可以用該命令啓動一個不是用Scrapy寫的爬蟲
  runspider     Run a self-contained spider (without creating a project)
  settings      Get settings values
  shell         Interactive scraping console

  //開始一個新的爬蟲項目,例:scrapy startproject 爬蟲工程名
  startproject  Create new project 

  //Scrapy版本,例:scrapy version
  version       Print Scrapy version  
  view          Open URL in browser, as seen by Scrapy

  [ more ]      More commands available when run from project directory

Use "scrapy <command> -h" to see more info about a command

2.5 Scrapy 的入門Demo

以下是跟着傳智播客老師寫的第一個Scrapy爬蟲的過程,這個過程幫助我進一步理解了Scrapy架構。

  1. 創建一個爬蟲項目:

    打開命令行,cd進入到自己的項目文件夾,輸入如下命令:

    scrapy startproject techInfo    //開始一個Scrapy爬蟲項目 
    scrapy genspider dwTechInfo "itcast.cn"  //創建一個爬蟲

    項目創建成功命令行顯示如下:
    爬蟲項目創建成功

    爬蟲創建成功命令行顯示如下:
    爬蟲創建成功

    這時,項目就創建好了在當前目錄下就會多出一個叫techInfo的文件夾,cd進入到techInfo文件夾,輸入如下命令查看工程文件結構:

    "find . -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g'"

    文件結構查看命令是經常要用到的命令,爲了簡化該命令,可以去設置.bash_profile文件(如果沒有用touch命令創建一個),打開文件在最後一行插入以下命令

    //將查看文件結構的命令簡化爲tree(tree也可以換成其他命名)
    alias tree="find . -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g'"

    保存後關閉,用source命令激活之後就可以用tree命令來查看當前目錄下的文件結構了。當前爬蟲工程techInfo目錄的文件結構如下圖。
    文件結構

    在當前目錄下有一個與爬蟲工程名字相同的techInfo文件夾和一個scrapy.cfg文件,其中在techInfo文件夾下有一個spiders文件夾和一系列的Python文件,完美契合了Scrapy架構:

    • techInfo文件夾
      • spyders文件夾:
        • dwTechInfo.py:爬蟲文件
      • _ init _.py:初始沒有任何內容,但不能刪(我也不知道爲什麼)
      • middlewares:爬蟲中間件
      • settings.py:爬蟲的設置文件,爬蟲啓動後按照設置文件的設置運行
      • items.py:在該文件中設置item字段,用於存儲爬取得到的信息
      • pipelines.py:管道文件,處理接收到的item數據
    • scrapy.cfg:包含了爬蟲工程的基本配置信息,如下

      [settings]
      default = techInfo.settings  //setting文件的位置
      project = techInfo   //爬蟲工程名稱

    對於第一個Scrapy爬蟲項目,爬蟲設置按照默認設置,同時不使用任何中間件,item數據在爬蟲文件中直接處理,因此可以暫且先只關注 items.py和dwTechInfo.py 兩個文件。

  2. 編寫代碼

    • 明確爬蟲目標:
      目標網頁
      如圖所示,爬取目標是讀取網頁中的老師的名字、職稱和個人信息,將其保存在json或者xml文件中。明確了目標後,找到 item.py 文件,編寫代碼如下:

      
      # -*- coding: utf-8 -*-
      
      
      
      # Define here the models for your scraped items
      
      #
      
      # See documentation in:
      
      
      # https://doc.scrapy.org/en/latest/topics/items.html
      
      
      import scrapy
      
      
      # 定義一個item數據類,用於保存爬蟲提取到的item數據
      
      class TechinfoItem(scrapy.Item):
          # define the fields for your item here like:
          # item數據中的name字段:用於保存老師的名字
          # 其中scrapy.Field()是Scrapy框架中用於創建一個字段的方法
          name = scrapy.Field()
          # 保存老師的職稱
          title = scrapy.Field()
          # 保存老師的個人信息
          info = scrapy.Field()
    • 編寫爬蟲文件 dwTechInfo.py :
      爬蟲創建成功後自動生成的爬蟲文件內容如下:

      
      # -*- coding: utf-8 -*-
      
      import scrapy
      
      class DwtechinfoSpider(scrapy.Spider):
          # 爬蟲名
          name = 'dwTechInfo'
          # 允許域名
          allowed_domains = ['itcast.cn']
          # 爬蟲開始的URL地址
          start_urls = ['http://www.itcast.cn/channel/teacher.shtml']
      
          # 函數功能:從下載成功的response響應文件中分析提取數據
          # 函數參數response: 下載器下載成功的響應文件
          def parse(self, response):
              pass

      接下來只需要在parse函數中分析提取response響應文件的數據,添加提取響應文件數據的代碼後,爬蟲文件如下:

      import scrapy
      
      
      # 導入Item數據類
      
      from techInfo.items import TechinfoItem
      
      class DwtechinfoSpider(scrapy.Spider):
      
      # 爬蟲名
      
      name = 'dwTechInfo'
      
      # 允許域名
      
      allowed_domains = ['itcast.cn']
      
      # 爬蟲開始的URL地址
      
      start_urls = ['http://www.itcast.cn/channel/teacher.shtml']
      
      
      # 函數功能:從下載成功的response響應文件中分析提取數據
      
      
      # 函數參數response: 下載器下載成功的響應文件
      
      def parse(self, response):
          root = response.xpath("//div[@class='li_txt']")
          items = []
          for node in root:
              # 創建爬蟲對象
              item = TechinfoItem()
              item['name'] = node.xpath("./h3/text()").extract()[0]
              item['title'] = node.xpath("./h4/text()").extract()[0]
              item['info'] = node.xpath("./p/text()").extract()[0]
      
              items.append(item)
      
              return items
              # print( response.body )
              # pass
  3. 運行爬蟲

    • 命令行運行爬蟲:執行如下命令運行爬蟲並將爬蟲獲取的內容保存

      
      # scrapy crawl 爬蟲名 -o 文件名 
      
      scrapy crawl dwTechInfo -o teacher.json
    • 配置 Pycharm 運行爬蟲:

      • 在Pycharm中打開爬蟲項目,在當前爬蟲項目的解釋器中安裝scrapy框架,點擊左下方的加號,在彈出的搜索框內輸入scrapy,點擊Install Packages,完成scrapy框架安裝,安裝成功如下圖所示
        這裏寫圖片描述
      • 在當前爬蟲項目下添加 begin.py 文件(注意begin文件所在位置)
        這裏寫圖片描述
      • 在begin.py文件中輸入以下命令:

        
        # 導入命令行
        
        from scrapy import cmdline
        
        # 命令行執行(之前一模一樣的運行爬蟲命令) scrapy crawl dwTechInfo -o teachers.json
        
        cmdline.execute("scrapy crawl dwTechInfo -o teachers.json".split())
      • 配置PyCharm
        點擊菜單欄中的Run->Edit Configurations,點擊左上角的加號添加一個Python模塊並在name框中爲新建的Python模塊起一個名字(筆者直接命名爲begin),在script path中選擇之前建立的begin.py,Working dirctory選擇爬蟲項目的路徑(最外層的techInfo),如下圖所示。最後點擊左上角的運行按鈕,運行爬蟲
        這裏寫圖片描述
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章