Python爬蟲開發與專案實戰--分散式程式

小瑾發表於2018-07-31

分散式的開發現在應該是炙手可熱。訊息佇列是實現分散式的一個方法。
Queue的整個使用過程
管理程式:
1) 建立佇列,宣告佇列中的元素個數
2) 定義佇列的回撥函式
3) 註冊佇列的回撥函式方法
4) 為QueueManager繫結地址及埠,設定authkey
5) 獲取佇列,入隊與出隊
任務程式:
1) 註冊用於獲取queue的方法名稱,任務程式只能通過名稱獲取在網路上獲取Queue
2) 根據ip,埠,authkey來連線伺服器

在windows中的程式碼如下:
taskManager.py

from queue import Queue
from multiprocessing.managers import BaseManager
from multiprocessing import freeze_support
task_number = 10
task_queue = Queue(task_number)
result_queue = Queue(task_number)
def get_task():
return task_queue
def get_result():
return result_queue
class QueueManager(BaseManager):
pass
def win_run():
QueueManager.register('get_task_queue',callable = get_task)
QueueManager.register('get_result_queue',callable=get_result)
manager = QueueManager(address=('127.0.0.1',8001),authkey=b'abc')
manager.start()
try:
task = manager.get_task_queue()
result = manager.get_result_queue()
for url in ['ImageUrl_'+str(i) for i in range(10)]:
print('put task %s ...'%url)
task.put(url)
print('try get result...')
for i in range(10):
print('result is %s'% result.get(timeout=10))
except:
print('Manager error')
finally:
manager.shutdown()

if __name__ == '__main__':
freeze_support()
win_run()

taskWorker.py

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=b'abc')
m.connect()
task=m.get_task_queue()
result=m.get_result_queue()
while(not task.empty()):
image_url = task.get(True,timeout=5)
print('run task download %s...'%image_url)
time.sleep(1)
result.put('%s---->success'%image_url)
print('worker exit.')

程式執行結果為:
server端
client端
注意點:
在建立QueueManager中如果authkey之後沒有加入b

報錯如下:
這裡寫圖片描述
那麼也許,我們先要了解下在Python中字串前面b的意義
在python中,字串前面可能會出現:
1. U 後面為中文組成的字串
2. R 後面為普通字串,主要如轉義字元等問題,用在正規表示式,檔案絕對地址中
3. B python3 中預設的str為unicode,b代表為bytes,是python2中的str
所以,在報錯中,也看到提示沒有encoding的提示
知識點:
1.freeze_support作用:
百度中沒有看到,直接到官網中去檢視:

Add support for when a program which uses multiprocessing has been frozen to produce a Windows executable. (Has been tested with py2exe, PyInstaller and cx_Freeze.)
One needs to call this function straight after the if __name__ == '__main__' line of the main module. For example:
from multiprocessing import Process, freeze_support
def f():
    print 'hello world!'
if __name__ == '__main__':
    freeze_support()
    Process(target=f).start()
If the freeze_support() line is omitted then trying to run the frozen executable will raise RuntimeError.
Calling freeze_support() has no effect when invoked on any operating system other than Windows. In addition, if the module is being run normally by the Python interpreter on Windows (the program has not been frozen), then freeze_support() has no effect.

來自 https://docs.python.org/2/library/multiprocessing.html
翻譯:
1)在windows下的多程式模式使用,如果Python直譯器已經正確的執行在windows中,該函式將沒有作用。
2)需要在main函式後面直接呼叫

2.pass作用
在python中pass是空語句,只是為了保持程式結構的完整性。

相關文章