爬蟲_小結02

 

一、scrapy框架專題部分python

(1)請簡要介紹下scrapy框架。
scrapy 是個快速,高層次的基於python的web爬蟲框架,用於抓取web站點,並從頁面中提取結構化的數據。
scrapy使用了Twisted異步網絡庫來處理網絡通訊。

(2)爲何要使用scrapy框架?scrapy框架有哪些優勢?
它更容易構建大規模的抓取項目
它異步處理請求,速度很是快
它能夠使用自動調節機制自動調整爬行速度

(3)scrapy框架有哪幾個組件/模塊?簡單說一下工做流程。

Scrapy Engine: 這是引擎,負責Spiders、ItemPipeline、Downloader、Scheduler中間的通信,信號、數據傳遞等等

Scheduler(調度器): 它負責接受引擎發送過來的requests請求,並按照必定的方式進行整理排列,入隊、並等待Scrapy Engine(引擎)來請求時,交給引擎。

Downloader(下載器):負責下載Scrapy Engine(引擎)發送的全部Requests請求,並將其獲取到的Responses交還給Scrapy Engine(引擎),由引擎交給Spiders來處理

Spiders:它負責處理全部Responses,從中分析提取數據,獲取Item字段須要的數據,並將須要跟進的URL提交給引擎,再次進入Scheduler(調度器)

Item Pipeline:它負責處理Spiders中獲取到的Item,並進行處理,好比去重,持久化存儲(存數據庫,寫入文件,總之就是保存數據用的)

Downloader Middlewares(下載中間件):你能夠看成是一個能夠自定義擴展下載功能的組件

Spider Middlewares(Spider中間件):你能夠理解爲是一個能夠自定擴展和操做引擎和Spiders中間‘通訊‘的功能組件
(好比進入Spiders的Responses;和從Spiders出去的Requests)

(4)scrapy如何實現分佈式抓取?
能夠藉助scrapy_redis類庫來實現。

原理:
在分佈式爬取時,會有master機器和slave機器,其中,master爲核心服務器,slave爲具體的爬蟲服務器。
在master服務器上搭建一個redis數據庫,並將要抓取的url存放到redis數據庫中,全部的slave爬蟲服務器在抓取的時候從redis數據庫中獲取連接,
因爲scrapy_redis自身的隊列機制,slave獲取的url不會相互衝突,而後抓取的結果最後都存儲到數據庫中。
master的redis數據庫中還會將抓取過的url的指紋存儲起來,用來去重。相關代碼在dupefilter.py文件中的request_seen()方法中能夠找到。

去重問題:
dupefilter.py 裏面的源碼:
def request_seen(self, request):
  fp = request_fingerprint(request)
  added = self.server.sadd(self.key, fp)
return not added
去重是把 request 的 fingerprint 存在 redis 上,來實現的。


二、其餘常見問題。
(1)爬蟲使用多線程好?仍是多進程好?爲何?
對於IO密集型代碼(文件處理,網絡爬蟲),多線程可以有效提高效率(單線程下有IO操做會進行IO等待,會形成沒必要要的時間等待,
而開啓多線程後,A線程等待時,會自動切換到線程B,能夠不浪費CPU的資源,從而提高程序執行效率)。
在實際的採集過程當中,既考慮網速和相應的問題,也須要考慮自身機器硬件的狀況,來設置多進程或者多線程。


(2)http和https的區別?
A. http是超文本傳輸協議,信息是明文傳輸,https則是具備安全性的ssl加密傳輸協議。
B. http適合於對傳輸速度、安全性要求不是很高,且須要快速開發的應用。如web應用,小的手機遊戲等等。而https適用於任何場景。


(3)數據結構之堆,棧和隊列的理解和實現
棧(stacks):棧的特色是後進先出。只能經過訪問一端來實現數據的儲存和檢索的線性數據結構。
隊列(queue):隊列的特色是先進先出。元素的增長只能在一端,元素的刪除只能在另外一端。增長的一端稱爲隊尾,刪除的一端稱爲隊首

棧:
stack = [1, 2, 3]
stack.append(4)
stack.append(5)
print(stack) # [1, 2, 3, 4, 5]
stack.pop()
stack.pop()
print(stack) # [1, 2, 3]

隊列:
from collections import dequeweb

queue = deque(['Eric', 'John', 'Michael'])
queue.append('Terry')
queue.append('Graham')
print(queue) # deque(['Eric', 'John', 'Michael', 'Terry', 'Graham'])
queue.popleft()
print(queue) # deque(['John', 'Michael', 'Terry', 'Graham'])redis

棧溢出的幾種狀況?
一、局部數組過大。當函數內部數組過大時,有可能致使堆棧溢出。
二、遞歸調用層次太多。遞歸函數在運行時會執行壓棧操做,當壓棧次數太多時,也會致使堆棧溢出。

解決方法:
一、用棧把遞歸轉換成非遞歸。
二、增大棧空間。數據庫

相關文章
相關標籤/搜索