多線程爬取圖片(生產者-消費者模式)

通過生產者-消費者模式實現多線程爬取圖片:

  1、生產者通過不斷爬取網頁中圖片的url存入圖片隊列中

  2、消費者通過圖片隊列中的url爬取圖片並下載到本地

  3、多線程的方式,爬取與下載同時進行,直到子線程結束,輸出爬取時間

 

 1 #多線程下載圖片
 2 #生產者-消費者模式
 3 import requests,queue,threading
 4 from lxml import etree
 5 from queue import Queue
 6 import os,time
 7 #生產者,將每個圖片的url放入隊列中
 8 class product(threading.Thread):
 9     headers = {
10         "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"
11     }
12     #初始化
13     def __init__(self,page_url,img_url):
14         super(product,self).__init__()
15         self.page_url = page_url
16         self.img_url = img_url
17     #子線程運行
18     def run(self):
19         while True:
20             #如果圖片url爬去完畢,則跳出循環,結束子線程
21             if self.page_url.empty():
22                 break;
23 
24             #獲取將爬取的頁面url,並解析
25             html = self.page_url.get()
26             self.parse_html(html)
27     #獲取圖片的url
28     def parse_html(self,html):
29         request = requests.get(html, headers=self.headers)
30         html = etree.HTML(request.text)
31         #解析html
32         imgs = html.xpath("//div[@class='page-content text-center']//img[@class!='gif']", encodding='gbk')
33         for img in imgs:
34             href = img.get("data-original")
35             name = img.get("alt")
36             #獲取後綴
37             suffix = os.path.splitext(href)[1]
38             filename = "img\\" + name + suffix
39             print(filename)
40             #將爬取的圖片url和圖片名字加入圖片隊列中
41             self.img_url.put((href,filename))
42 #消費者,根據圖片url爬取圖片
43 class consume(threading.Thread):
44     def __init__(self,page_url,img_url):
45         super(consume,self).__init__()
46         self.page_url = page_url
47         self.img_url = img_url
48     def run(self):
49         while True:
50             #如果圖片隊列爲空且頁面隊列爲空,則推出循環
51             if self.page_url.empty() and self.img_url.empty():
52                 break
53             href,filename = self.img_url.get()
54             res = requests.get(href)
55             with open(filename, 'wb') as fp:
56                 fp.write(res.content)
57 def main():
58     #基本url
59     base_url = "http://www.doutula.com/photo/list/?page={}"
60     #設置頁面隊列爲10,圖片隊列爲200
61     page_url = Queue(10)
62     img_url = Queue(200)
63     #把需要爬取的網頁url放入隊列中
64     for i in range(1,10):
65         url = base_url.format(i)
66         page_url.put(url)
67     #設置生產者,開始爬取每個網頁的圖片地址
68     for i in range(8):
69         t = product(page_url,img_url)
70         t.start()
71     #設置消費者,根據圖片隊列中的url爬取圖片
72     for j in range(8):
73         tt = consume(page_url,img_url)
74         tt.start()
75         #設置消費者子線程運行完之後,纔會推出main主線程
76         tt.join()
77 
78 if __name__ == '__main__':
79     times = time.time()
80     tmain = threading.Thread(target=main)
81     tmain.start()
82     tmain.join()
83     times1 = time.time()
84     print(times1-times)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章