python多線程爬取圖片二


上一篇的多線程是使用類創建的,這一次使用函數創建多線程,還是同一個網站https://www.quanjing.com/category/1286521/1.html,

代碼如下:

 1 # 多線程,自動創建文件夾,每個頁面單獨存儲一個文件夾
 2 
 3 import requests
 4 import threading
 5 import re
 6 import time
 7 import queue
 8 import os
 9 from bs4 import BeautifulSoup
10 
11 
12 string = 'https://www.quanjing.com/category/1286521/'
13 url_queue = queue.Queue()
14 pipei = re.compile('lowsrc="(.*?)" m=')        # 定義正則表達式,匹配出每一張圖片的鏈接
15 
16 
17 def get_url(page):          # 根據傳入的頁面數,創建1-page每個頁面的url
18     for i in range(1, page+1):
19         url = string + str(i) + '.html'      # 拼接url
20         url_queue.put(url)            # 把每個url放入隊列中
21     # print(url_queue.queue)
22 
23 
24 def spider(url_queue):      # 爬取函數
25     url = url_queue.get()    # 從隊列中取出最前面的url
26     floder_count = url[-7:-5]  # 判斷當前爬取的為第幾頁,用於后面的創建文件夾,如果頁數為兩位數,則會截取當前頁數,如果為一位數字,則會截取當前頁數和前面的‘/’符號
27     if floder_count[0] == '/':
28         floder_name = floder_count[1]
29     else:
30         floder_name = floder_count
31     os.mkdir('第{0}頁'.format(floder_name)) # mkdir創建文件夾
32     html = requests.get(url=url).text
33     soup = BeautifulSoup(html, 'lxml')    # 對源碼進行解析
34     ul = soup.find_all(attrs={"class": "gallery_list"})    # 提取出圖片鏈接的部分
35     # print(ul)
36     lianjies = re.findall(pipei, str(ul))       # 匹配出每一張圖片的鏈接,正則匹配必須是字符串類型
37     i = 1
38     for lianjie in lianjies:
39         # print(lianjie)
40         result = requests.get(url=lianjie).content    # 二進制方式請求每張圖片,並存儲。
41         with open('第{0}頁\{1}.jpg'.format(floder_name, i), 'ab') as f:
42             f.write(result)
43         print('第{0}頁第{1}張存儲完成'.format(floder_name, i))
44         i += 1
45 
46     if not url_queue.empty():    # 如果隊列未空,則該線程繼續工作,從隊列中取出url
47         spider(url_queue)
48 
49 
50 def main():      # main函數,用於線程的創建,線程的啟動
51     queue_list = []    # 線程列表
52     queue_count = 3    # 線程數量
53     for i in range(queue_count):
54         t = threading.Thread(target=spider, args=(url_queue, ))  # 創建線程,第一個參數為線程要調用的函數,第二個參數為函數的參數
55         queue_list.append(t)        # 把線程加入隊列
56     for t in queue_list:    # 線程開始
57         t.start()
58     for t in queue_list:  # 等待所有線程結束
59         t.join()
60 
61 
62 if __name__ == '__main__':
63     page = int(input("請輸入需要爬取的頁數:"))
64     get_url(page)
65     start_time = time.time()
66     main()
67     print("test3用時:%f" % (time.time() - start_time))    # 計算爬取用時                                                                                                    

 在寫代碼時,遇到了兩點困難:一是隊列未空時,怎么讓線程繼續工作。剛開始是在if判斷后調用main函數,但這樣做等於又重新定義了新的線程,並不是之前的線程在繼續工作,且有時候會存在爬取不完的情況,后來嘗試調用spider函數,爬取成功

第二個困難是文件夾的創建,剛開始沒有對截圖的兩個字符進行判斷,導致創建失敗,百度一下后發現可以用makedirs解決,試了后發現這樣創建的是多級目錄,也不行,(可能是‘/’字符的緣故),后來加了一個判斷,才解決這一問題。

寫完這兩個多線程爬蟲,才算是了解了線程的工作機制的程序。(ps:若有錯誤的地方,歡迎大佬隨時指正。。xixix)


免責聲明!

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



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