爬蟲篇-python爬蟲中多線程的使用


queue介紹

  • queue是python的標准庫,俗稱隊列.可以直接import引用,在python2.x中,模塊名為Queue。python3直接queue即可
  • 在python中,多個線程之間的數據是共享的,多個線程進行數據交換的時候,不能夠保證數據的安全性和一致性,所以當多個線程需要進行數據交換的時候,隊列就出現了,隊列可以完美解決線程間的數據交換,保證線程間數據的安全性和一致性。

#多線程實戰栗子(糗百)
#用一個隊列Queue對象,
#先產生所有url,put進隊列;
#開啟多線程,把queue隊列作為參數傳入
#主函數中讀取url

import requests
from queue import Queue
import re,os,threading,time
# 構造所有ip地址並添加進queue隊列
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'
}
urlQueue = Queue()
[urlQueue.put('http://www.qiumeimei.com/image/page/{}'.format(i)) for i in range(1,14)]
def get_image(urlQueue):

    while True:
        try:
            # 不阻塞的讀取隊列數據
            url = urlQueue.get_nowait()
            # i = urlQueue.qsize()
        except Exception as e:
            break
        print('Current Thread Name %s, Url: %s ' % (threading.currentThread().name, url))
        try:
            res = requests.get(url, headers=headers)
            url_infos = re.findall('data-lazy-src="(.*?)"', res.text, re.S)
            for url_info in url_infos:
                if os.path.exists(img_path + url_info[-20:]):
                    print('圖片已存在')
                else:
                    image = requests.get(url_info, headers=headers)
                    with open(img_path + url_info[-20:], 'wb') as fp:
                        time.sleep(1)
                        fp.write(image.content)
                    print('正在下載:' + url_info)
        except Exception as e:
            print(e)

if __name__ == '__main__':
    startTime = time.time()
    # 定義圖片存儲路徑
    img_path = './img/'
    if not os.path.exists(img_path):
        os.mkdir(img_path)
    threads = []
    # 可以調節線程數, 進而控制抓取速度
    threadNum = 4
    for i in range(0, threadNum):
        t = threading.Thread(target=get_image, args=(urlQueue,))
        threads.append(t)
    for t in threads:
        t.start()
    for t in threads:
        # 多線程多join的情況下,依次執行各線程的join方法, 這樣可以確保主線程最后退出, 且各個線程間沒有阻塞
        t.join()
    endTime = time.time()
    print('Done, Time cost: %s ' % (endTime - startTime))

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM