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
class QueueManager(BaseManager):
pass
def run():
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':
freeze_support()
run()
上面就是咱們的服務進程,我把解析都寫在了裏面,你們能夠仔細看一下,接下來咱們來寫任務進程(taskWorker),建立任務進程也比較簡單,只有簡單的四步:
建立一個相似的QueueManager對象,使用QueueManager註冊用於獲取queue的方法名稱,任務進程只能經過名稱來在網絡上獲取queue,因此這裏必定要注意服務端和任務端的名稱要相同。
連接服務器,端口和指令必定要與服務端相同
從網絡上獲取queue,而且將其本地化。
從task對列中獲取任務,而且把結果寫入result對列。
import time
from multiprocessing.managers import BaseManager
class QueueManager(BaseManager):
pass
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()
task = m.get_task_queue()
result = m.get_result_queue()
while(not task.empty()):
url = task.get(True, timeout = 5)
print("run task download %s" %url)
time.sleep(1)
result.put("%s --->success" %url)
print("exit")
詳細的步驟也寫在裏面了,固然這個任務隊列,咱們是能夠建立多個的,每一個任務進程都會完成本身的事,而不會干擾其餘的任務進程,這也就讓咱們的url不會重複的去爬取,從而完美的實現了多個進程來爬取咱們的任務。
以上就是一個很是簡單的分佈式進程的爬蟲小案例,你們能夠經過這種方式去實戰本身的一個小項目,在這裏還說一下,咱們是能夠將咱們的任務分佈到多臺機器上的,這樣咱們就實現了大規模的爬取。
以上就是小編今天爲你們帶來的一些Python經常使用的爬蟲代碼。
在學習中有迷茫不知如何學習的朋友小編推薦一個學Python的學習q u n 315 -346- 913能夠來了解一塊兒進步一塊兒學習!免費分享視頻資料
轉自JAP君