【Python3.6爬蟲學習記錄】(十四)多執行緒爬蟲模板總結
阿新 • • 發佈:2019-02-15
前言:這幾天忙活的做個網頁玩玩,網上也沒有教程。買個域名又得解析,又得備案,真是麻煩,覺得一個簡單的HTML網頁應該用不到那麼麻煩吧。
昨天又看了幾個關於多執行緒爬蟲的例子,覺得很好,提煉出來,總結幾個應用模板。
目錄
一 多執行緒Threading模組
1-1 簡單的函式建立多執行緒
## 簡單應用thread模組
import socket
import threading
import requests
tasks = []
lock = threading.Lock() # 建立一個鎖
# 執行緒工作函式
def worker(i):
socket.setdefaulttimeout(5 ) # 設定全域性超時時間
try:
r = requests.get(url)
lock.acquire() # 獲得鎖
print('Processing ',i)
lock.release() # 釋放鎖
except Exception as e:
lock.acquire()
print(e)
lock.release()
# 多執行緒
threads = []
for i in range(len(tasks)):
# 引數包括,目標函式,以及操作物件序號
thread = threading.Thread(target=worker, args=[i])
# 將全部IP加入執行緒,並開始多執行緒
threads.append(thread)
thread.start()
# 阻塞主程序,等待所有子執行緒結束
# 通俗的將,就是執行完上述的過程再結束
for thread in threads:
thread.join()
2-1 用類包裝執行緒物件
import threading
import time
class myThread(threading.Thread):
'''
構造方法
'''
def __init__(self, threadID, name, counter):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.counter = counter
def run(self):
print("Starting " + self.name)
'''開啟網頁以及查詢等操作
'''
# 獲得鎖,成功獲得鎖定後返回True
# 可選的timeout引數不填時將一直阻塞直到獲得鎖定
# 否則超時後將返回False
threadLock.acquire()
'''儲存檔案,列印操作
'''
print(self.name, self.counter, 3)
# 釋放鎖
threadLock.release()
threadLock = threading.Lock()
threads = []
'''建立,開始,新增執行緒組
'''
for i in range(1,3):
# 建立新執行緒
thread = myThread(i, "Thread-%s"%i, i)
# 開啟新執行緒
thread.start()
# 新增執行緒到執行緒列表
threads.append(thread)
# 等待所有執行緒完成
for t in threads:
t.join()
print("iting Main Thread")
二 多執行緒Queue模組
2-1 使用Queue 與 Threading模組
import os
import random
import threading
import time
from queue import Queue
import requests
class myThread(threading.Thread):
def __init__(self,func):
# 呼叫父類建構函式
super(myThread, self).__init__()
# 傳入執行緒函式邏輯
self.func=func
def run(self):
'''
重寫run方法
'''
self.func()
# 功能函式
def worker():
global Q
while not Q.empty():
# 獲得任務
item = Q.get()
'''
執行的任務
'''
# 原來寫Queue,沒有初始化
Q.task_done()
'''其他功能性函式
'''
# 主函式
def main():
global Q
threads = []
# 向佇列中放入任務
for task in range(len(tasks)):
Q.put(tasks[task])
# 執行執行緒
for i in range(thread_num):
thread = myThread(worker)
thread.start()
threads.append(thread)
# 等待執行緒結束
for thread in threads :
thread.join()
# 等待所有執行緒結束
Q.join()
# 本專案中執行
if __name__ == '__main__':
# 無限制佇列
Q = Queue()
# 執行緒數
thread_num = 100
# 任務物件列表
tasks = []
start = time.time()
main()
end = time.time()
print('It takes ',end-start)
三 多程序併發模組
3-1 Queue 與 Threading實現併發
# 多執行緒併發模板
from queue import Queue
from threading import Thread
from time import sleep
#q是任務佇列
#NUM是併發執行緒總數
#JOBS是有多少任務
q = Queue()
NUM = 2
JOBS = 10
#具體的處理函式,負責處理單個任務
def do_somthing_using(arguments):
print(arguments)
#這個是工作程序,負責不斷從佇列取資料並處理
def working():
while True:
arguments = q.get()
do_somthing_using(arguments)
sleep(1)
q.task_done()
#fork NUM個執行緒等待佇列
for i in range(NUM):
t = Thread(target=working)
t.setDaemon(True)
t.start()
#把JOBS排入佇列
for i in range(JOBS):
q.put(i)
#等待所有JOBS完成
q.join()
3-2 multiprocessing模組實現併發
from multiprocessing import Pool
pool = Pool(8)
data_list = pool.map(get, url_list)
pool.close()
pool.join()
後記:
有些並不是很理解,但是可以直接套模板。簡單簡單點來,可以用類包裝Threading模組,但是如果應用物件很多,這樣一下子把所有的執行緒都開了,會卡死,應該有解決辦法吧,目前還沒查到;然後,如果任務物件很多,就直接用queue模組,只開啟一定的執行緒,依次執行,目前應用的蠻好,再看;最後,關於多程序併發的還不是很清楚,之後在瞭解吧。期間還看到了協程,等知識不夠用了再學。