今天試着把前面那個爬取圖片的爬蟲改成了多線程爬取,雖然最后可以爬取存儲圖片了,但仍存在一些問題。網址還是那個網址https://www.quanjing.com/category/1286521/1.html,
下面是代碼,難點直接在后面注釋了。
# 多線程爬取,每個線程爬取一個頁面 import requests import threading import queue from bs4 import BeautifulSoup import re import time string = "https://www.quanjing.com/category/1286521/" pipei = re.compile('<img.*?lowsrc="(.*?)"') class spiders(threading.Thread): name = 1 # 累加變量,用來給每張圖片命名 def __init__(self, queue, page): threading.Thread.__init__(self) self.queue = queue self.page = page def run(self): # 定義線程開始函數 while not self.queue.empty(): url = self.queue.get_nowait() # print(url) self.request_url(url) def request_url(self, url): # 爬取並存儲每一頁的圖片 html = requests.get(url=url).text soup = BeautifulSoup(html, 'lxml') li = str(soup.find_all(attrs={'class': "gallery_list"})) # 根據class標簽屬性找出所有的圖片鏈接 lianjies = re.findall(pipei, li) # 正則匹配出一頁中每一個圖片的鏈接 for lianjie in lianjies: result = requests.get(url=lianjie).content # 獲取圖片的二進制數據 # 以二進制的方式存儲圖片 with open('E:\py project\quanjingwang\image{0}\{1}.jpg'.format(self.page, self.name), 'ab+') as f: f.write(result) print("第{0}張存儲完成".format(self.name)) self.name += 1 # 命名 # 創建多線程函數 def main(): url_queue = queue.Queue() for i in range(1, 11): url = string + str(i) + ".html" url_queue.put(url) thread_list = [] # 線程列表 thread_counter = 5 # 線程數量,根據線程數量在相同目錄下創建image0-4五個文件夾,用於存儲對應線程的爬取結果,image0對應線程1 for i in range(thread_counter): t = spiders(url_queue, i) thread_list.append(t) for t in thread_list: t.start() # for t in thread_list: # print("線程id:%d" % t.ident) # 獲取線程id # print("線程name:%s" % t.getName()) # 獲取線程名 for t in thread_list: t.join() if __name__ == '__main__': start_time = time.time() main() print("五線程用時:%f" % (time.time() - start_time))
剛開始,我想把爬取的所有圖片都放在一個文件夾了,但卻由於命名的問題,總是被覆蓋,每次都只有一頁的圖片,最后用類中的靜態變量解決(name)。不過就在剛在突然想到完全可以換一種命名方式解決,比如每張圖片都有一個自己的標題,用標題命名不但解決的這個問題,還更加直觀、利用查找。(自己tcl。。。若文章有錯誤,歡迎大家隨之指正。。。)