以前的文章咱們介紹了幾種能夠爬取網站信息的模塊,並根據這些模塊爬取了《糗事百科》的糗百內容,本章咱們來看一下用於專門爬取網站信息的框架 Scrapy。html
Scrapy是用純Python實現一個爲了爬取網站數據、提取結構性數據而編寫的應用框架,用途很是普遍。Scrapy 使用了 Twisted['twɪstɪd]
(其主要對手是Tornado)異步網絡框架來處理網絡通信,能夠加快咱們的下載速度,不用本身去實現異步框架,而且包含了各類中間件接口,能夠靈活的完成各類需求。web
Scrapy Engine(引擎)
: 負責Spider
、ItemPipeline
、Downloader
、Scheduler
中間的通信,信號、數據傳遞等。json
Scheduler(調度器)
: 它負責接受引擎
發送過來的Request請求,並按照必定的方式進行整理排列,入隊,當引擎
須要時,交還給引擎
。網絡
Downloader(下載器)
:負責下載Scrapy Engine(引擎)
發送的全部Requests請求,並將其獲取到的Responses交還給Scrapy Engine(引擎)
,由引擎
交給Spider
來處理,架構
Spider(爬蟲)
:它負責處理全部Responses,從中分析提取數據,獲取Item字段須要的數據,並將須要跟進的URL提交給引擎
,再次進入Scheduler(調度器)
,框架
Item Pipeline(管道)
:它負責處理Spider
中獲取到的Item,並進行進行後期處理(詳細分析、過濾、存儲等)的地方.dom
Downloader Middlewares(下載中間件)
:你能夠看成是一個能夠自定義擴展下載功能的組件。異步
Spider Middlewares(Spider中間件)
:你能夠理解爲是一個能夠自定擴展和操做引擎
和Spider
中間通訊
的功能組件(好比進入Spider
的Responses;和從Spider
出去的Requests)scrapy
Scrapy框架官方網址:http://doc.scrapy.org/en/latestide
Scrapy中文維護站點:http://scrapy-chs.readthedocs.io/zh_CN/latest/index.html
咱們能夠經過 pip install scrapy 進行 scrapy 框架的下載安裝。
接下來咱們就來建立一個簡單的爬蟲目錄並對其中的目錄結構進行說明。
首先咱們進入咱們的工做目錄,而後在終端運行 scrapy startproject qiushi ,這樣咱們就建立了一個叫 qiushi 的基於 scrapy 框架構建的爬蟲項目,目錄結構以下:
下面來簡單介紹一下各個主要文件的做用:
scrapy.cfg :項目的配置文件
qiushi/ :項目的Python模塊,將會從這裏引用代碼
qiushi/items.py :項目的目標文件
qiushi/middlewares/ :項目的中間件
qiushi/pipelines.py :項目的管道文件
qiushi/settings.py :項目的設置文件
對於目錄中的 __init__.py 文件,是一個空文件,咱們能夠不去管理,可是也不能刪除,不然項目將沒法運行。
items.py 使咱們要寫代碼邏輯的文件,相關的爬取代碼在這裏面寫。
middlewares.py 是一箇中間件文件,能夠將一些自寫的中間件在這裏面寫。
pipelines.py 是一個管道文件,咱們爬取信息的處理能夠在這裏面寫。
settings.py 是一個設置文件,裏面是咱們爬取信息的一些相關信息,咱們能夠根據須要對其進行球蓋,固然也能夠按照裏面給定的默認設置。
接下來咱們就來爬取一下以前咱們爬取過的糗百的內容。
咱們要爬取的網站是 https://www.qiushibaike.com/text/page/1/ 。
咱們經過 Xpath Helper 的谷歌插件通過分析獲取到咱們想要的內容爲: //div[contains(@id,"qiushi_tag")]
咱們要爬取的是發佈糗百的 做者,頭像和糗事內容。
咱們打開 items.py,而後將其改成以下代碼:
1 import scrapy 2 3 class QiushiItem(scrapy.Item): 4 # define the fields for your item here like: 5 name = scrapy.Field() # 做者 6 imgUrl = scrapy.Field() # 頭像 7 content = scrapy.Field() # 內容
而後咱們在 qiushi/qiushi/spiders 文件夾下建立一個 qiushiSpider.py 的文件,代碼以下:
1 import scrapy 2 from ..items import QiushiItem 3 4 5 class QiushiSpider(scrapy.Spider): 6 # 爬蟲名 7 name = "qiubai1" 8 # 容許爬蟲做用的範圍,不能越界 9 allowd_domains = ["https://www.qiushibaike.com/"] 10 # 爬蟲起始url 11 start_urls = ["https://www.qiushibaike.com/text/page/1/"] 12 13 # 咱們無需再像以前利用 urllib 庫那樣去請求地址返回數據,在 scrapy 框架中直接利用下面的 parse 方法進行數據處理便可。 14 def parse(self, response): 15 # 經過 scrayy 自帶的 xpath 匹配想要的信息 16 qiushi_list = response.xpath('//div[contains(@id,"qiushi_tag")]') 17 for site in qiushi_list: 18 # 實例化從 items.py 導入的 QiushiItem 類 19 item = QiushiItem() 20 # 根據查詢發現匿名用戶和非匿名用戶的標籤不同 21 try: 22 # 非匿名用戶 23 username = site.xpath('./div/a/img/@alt')[0].extract() # 做者 24 imgUrl = site.xpath('./div/a/img/@src')[0].extract() # 頭像 25 except Exception: 26 # 匿名用戶 27 username = site.xpath('./div/span/img/@alt')[0].extract() # 做者 28 imgUrl = site.xpath('./div/span/img/@src')[0].extract() # 頭像 29 content = site.xpath('.//div[@class="content"]/span[1]/text()').extract() 30 item['username'] = username 31 item['imgUrl'] = "https:" + imgUrl 32 item['content'] = content 33 34 # 將獲取的數據交給 pipeline 管道文件 35 yield item
接下來咱們打開 settings.py,settings.py 內能夠根據咱們的需求本身去修改,因爲內容過多,在後續的章節若是有須要用到的咱們單獨再說。
參考文檔:https://scrapy-chs.readthedocs.io/zh_CN/1.0/topics/settings.html#topics-settings-ref
在該案例中咱們須要作的修改以下:
1 # Crawl responsibly by identifying yourself (and your website) on the user-agent 2 USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36' 3 # Configure item pipelines 4 # See https://doc.scrapy.org/en/latest/topics/item-pipeline.html 5 ITEM_PIPELINES = { 6 'qiushi.pipelines.QiushiPipeline': 300, 7 }
在上面的代碼中,咱們加入了請求報頭,而後注入一個管道文件,接下來咱們打開 oippelines.py 來完成這個管道文件,代碼以下:
1 import json 2 3 4 class QiushiPipeline(object): 5 def __init__(self): 6 self.file = open('qiushi.json', 'a') 7 8 def process_item(self, item, spider): 9 content = json.dumps(dict(item), ensure_ascii=False) + ",\n" 10 self.file.write(content) 11 return item 12 13 def close_spider(self, spider): 14 self.file.close()
這個管道文件其實就是咱們將爬取到的數據存儲到本地一個叫 qiushi.json 的文件中,其中 def process_item 會接受咱們的數據 item,咱們就能夠對其進行相關操做了。
至此咱們就完成了一個簡單的爬取糗百的爬蟲,能夠看出咱們不須要再像以前那樣考慮太多操做時的細節,scrapy 框架會自動爲咱們處理,咱們只須要按照相應的流程對咱們的數據作處理就好了。
在控制檯輸入 scrapy crawl qiubai 便可運行改程序,其中「qiubai」 qiushiSpider.py 中爲咱們定義的 name 名,最終結果以下: