十分鐘搞懂分佈式爬蟲

1.預備知識windows

服務器

今天我們來扯一扯分佈式進程爬蟲,對爬蟲有所瞭解的都知道分佈式爬蟲這個東東,今天咱們來搞懂一下分佈式這個概念,從字面上看就是分開來佈置,確實如此它是能夠分開來運做的。網絡

分佈式進程就是將進程分佈到多臺機器上去,充分利用每一臺機器來完成咱們的爬蟲任務。分佈式進程須要用到multiprocessing模板,multiprocessing模板不但支持多進程,它的managers子模塊還支持把多進程分佈到多臺機器上。分佈式

咱們能夠寫一個服務進程做爲調度者,而後將咱們的爬蟲任務分佈給其餘的多個進程當中去,咱們依靠網絡通訊來管理這些進程。函數

學習

2.模擬一個分佈式進程爬蟲網站

咱們來模擬進行一個分佈式進程的爬蟲吧,就好比咱們須要抓取某個圖片網站的全部圖片,若是用咱們的分佈式進程的思想,咱們會建立一個進程負責抓取圖片的連接地址,而後將這些連接地址存放到Queue中,另外的進程負責從Queue中讀取連接進行圖片的下載或者進行其餘操做(存在本地).url

其實咱們的Queue是暴露在網絡中的,經過分佈式就是將其進行了封裝,其實也就是所謂的本地隊列的網絡化。code

接下來,咱們來分析一下如何去建立一個分佈式的服務進程,整體能夠分爲六步:視頻

首先咱們須要創建一個隊列queue,這個主要用做進程之間的通訊。整體來講就是兩種進程,一種是服務進程,一種是任務進程。服務進程建立任務隊列task_queue,用做傳遞任務給任務進程的通道。服務進程又建立result_queue,做爲任務進程完成任務後回覆服務進程的通道。在分佈式進程的環境下,咱們須要經過Queuemanager 得到的Queue接口來添加任務。

把咱們在第一步中隊列在網絡上進行註冊,暴露給其餘的進程或者主機,註冊後得到網絡隊列,至關於本地隊列的映像。

創建Queuemanager的對象,而且實例化,綁定端口和口令

啓動第三步中創建的實例,即啓動管理manager,監管信息通道

經過管理實例的方法獲取到經過網絡訪問的queue對象,也就是把網絡對象實體化成本地的一個隊列。

建立任務到「本地」隊列中,自動上傳任務到網絡隊列中,分配給任務進程進行處理。

咱們就來寫一下服務進程的代碼 taskManager.py:

import queue

from multiprocessing.managers import BaseManager

from multiprocessing import freeze_support

任務個數

task_num = 500

定義收發隊列

task_queue = queue.Queue(task_num)

result_queue = queue.Queue(task_num)

def get_task():

return task_queue

def get_result():

return result_queue

建立相似的QueueManager

class QueueManager(BaseManager):

pass

def run():

Windows下綁定調用接口不能使用lambda,因此只能先定義函數再綁定

QueueManager.register('get_task_queue', callable = get_task)

QueueManager.register('get_result_queue', callable=get_result)

#綁定端口並設置驗證口令,windows下須要填寫ip地址,Linux中不填默認爲本地

manager = QueueManager(address=('127.0.0.1', 8001), authkey='jap'.encode('utf-8'))

啓動

manager.start()

try:

經過網絡獲取任務隊列和結果隊列

task = manager.get_task_queue()

result = manager.get_result_queue()

添加任務

for url in ["JAP君url:"+str(i) for i in range(500)]:

print("添加任務 %s" %url)

task.put(url)

print("正在獲取結果...")

for i in range(500):

print("result is %s" %result.get(timeout=10))

except:

print('Manager error')

finally:

必定要關閉,不然會報管道未關閉的錯

manager.shutdown()

if name == 'main':

windows下多進程可能會出現問題,添加這句話能夠解決

freeze_support()

run()

上面就是咱們的服務進程,我把解析都寫在了裏面,你們能夠仔細看一下,接下來咱們來寫任務進程(taskWorker),建立任務進程也比較簡單,只有簡單的四步:

  1. 建立一個相似的QueueManager對象,使用QueueManager註冊用於獲取queue的方法名稱,任務進程只能經過名稱來在網絡上獲取queue,因此這裏必定要注意服務端和任務端的名稱要相同。

  2. 連接服務器,端口和指令必定要與服務端相同

  3. 從網絡上獲取queue,而且將其本地化。

  4. 從task對列中獲取任務,而且把結果寫入result對列。

import time

from multiprocessing.managers import BaseManager

建立相似的QueueManager

class QueueManager(BaseManager):

pass

第一步:使用QueueManager註冊用於獲取Queue的方法名稱

QueueManager.register('get_task_queue')

QueueManager.register('get_result_queue')

第二步:連接到服務器

server_addr = '127.0.0.1'

print('Connect to server %s' %server_addr)

端口和驗證的口令必定要保證相同

m = QueueManager(address = (server_addr, 8001), authkey='jap'.encode('utf-8'))

從網絡鏈接:

m.connect()

第三步:獲取queue的對象

task = m.get_task_queue()

result = m.get_result_queue()

第四步:從task隊列中獲取任務,並把結果寫入result隊列

while(not task.empty()):

url = task.get(True, timeout = 5)

print("run task download %s" %url)

time.sleep(1)

將結果寫入result隊列

result.put("%s --->success" %url)

print("exit")

詳細的步驟也寫在裏面了,固然這個任務隊列,咱們是能夠建立多個的,每一個任務進程都會完成本身的事,而不會干擾其餘的任務進程,這也就讓咱們的url不會重複的去爬取,從而完美的實現了多個進程來爬取咱們的任務。

以上就是一個很是簡單的分佈式進程的爬蟲小案例,你們能夠經過這種方式去實戰本身的一個小項目,在這裏還說一下,咱們是能夠將咱們的任務分佈到多臺機器上的,這樣咱們就實現了大規模的爬取。

以上就是小編今天爲你們帶來的一些Python經常使用的爬蟲代碼。

在學習中有迷茫不知如何學習的朋友小編推薦一個學Python的學習q u n 315 -346- 913能夠來了解一塊兒進步一塊兒學習!免費分享視頻資料

轉自JAP君

相關文章
相關標籤/搜索