Python爬蟲15--爬蟲遇上多執行緒,速度更上一層樓,爬取1000張圖片連一分鐘也不要!

大大打打發表於2021-01-03

將多執行緒和爬蟲結合,能將爬取速度更上一層樓,爬取1000張圖片連一分鐘也不要!

百度圖片對於爬蟲相當的友好,基本不需要做反反爬蟲的設定,點贊 :)

1.分析百度圖片網址:

從百度進去搜尋圖片,例如搜尋 “拳皇” ,很大可能會看到位址列出現一大坨東西,就像這樣:

https://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=result&fr=&sf=1&fmq=1609662428291_R&pv=&ic=&nc=1&z=&hd=&latest=&copyright=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&hs=2&sid=&word=%E6%8B%B3%E7%9A%87

看的人頭疼,將這個難看的URL地址拿到URL解析網站解析一下看看,發現最後的一串資料就是我們要找的圖片名稱:

 其實,URL中有很多內容對於我們爬蟲來說,其實是可有可無的,大部分 “&” 符號後面的引數都可以去掉,“?”之後的引數也是如此,但這個URL是例外。

不認識的都可以試著刪除,要用的話大不了之後再加回來,得到了如下URL地址,怎麼樣,舒服多了吧。這就是初始URL了。

https://image.baidu.com/search/index?tn=baiduimage&word=%E6%8B%B3%E7%9A%87

2.尋找圖片資訊

開啟瀏覽器自帶的抓包工具,重新載入一下網站,耐心的尋找響應,最後終於找到了。圖片的地址居然藏在Json中,那事情似乎變得簡單了起來。

3.直接上程式碼吧,請求圖片可能比較慢,直接上5個執行緒。不用怕速度太快被反爬

import requests
import json
import threading
from queue import Queue
import os

class ImgSpider:
    def __init__(self, img_name, list_number):
        self.img_name = img_name
        self.list_number = int(list_number//30) + 1
        self.original_url = 'https://image.baidu.com/search/acjson?tn=resultjson_com&pn={}&ipn=rj&word={}'
        self.start_url = 'https://image.baidu.com/search/acjson?tn=resultjson_com&pn=0&ipn=rj&word={}'.format(img_name)
        self.headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36"}
        self.url_list_queue = Queue()
        self.response_url_queue = Queue()
        self.img_list_queue = Queue()
        self.img_content_queue = Queue()

    # 生成目標url列表
    def url_list(self):
        for i in range(self.list_number):
            url = self.original_url.format(i * 30, self.img_name)
            self.url_list_queue.put(url)

    # 對目標url列表進行爬取
    def parse_url(self):
        while True:
            url = self.url_list_queue.get()
            response = requests.get(url, headers=self.headers)
            self.response_url_queue.put(response.content.decode())
            self.url_list_queue.task_done()

    # 提取圖片地址
    def get_img_url(self):
        while True:
            content = self.response_url_queue.get()
            content = json.loads(content)
            for i in content["data"][0:-1]:
                url = i['thumbURL']
                # print(url)
                self.img_list_queue.put(url)
            self.response_url_queue.task_done()

    # 從圖片列表中取出地址傳送請求
    def parse_img_list(self):
        while True:
            url = self.img_list_queue.get()
            print('正在請求:', url)
            response = requests.get(url, headers=self.headers)
            self.img_content_queue.put(response.content)
            self.img_list_queue.task_done()

    # 儲存圖片
    def save_img(self):
        os.mkdir(self.img_name)
        count = 0
        while True:
            if self.img_content_queue:
                path = '{}/{}'.format(self.img_name, self.img_name)
                with open(path + '{}.png'.format(count), 'wb') as f:
                    content = self.img_content_queue.get()
                    f.write(content)
                    count += 1
                    self.img_content_queue.task_done()

    def run(self):
        # 1.獲取start_url,構造url_list
        self.url_list()
        # 2.傳送請求獲取url資訊
        ls = []
        t1 = threading.Thread(target=self.parse_url)
        ls.append(t1)
        # 3.提取圖片地址
        t2 = threading.Thread(target=self.get_img_url)
        ls.append(t2)
        # 4.請求圖片資訊
        for i in range(5):
            t3 = threading.Thread(target=self.parse_img_list)
            ls.append(t3)
        # 5.儲存圖片
        t4 = threading.Thread(target=self.save_img)
        ls.append(t4)
        for i in ls:
            i.setDaemon(True)
            i.start()
        self.url_list_queue.join()
        self.response_url_queue.join()
        self.img_list_queue.join()
        self.img_content_queue.join()


img_name = input("輸入要下載的圖片名稱:")
list_number = int(input("下載數量(自動補齊成30的倍數):"))
img = ImgSpider(img_name, list_number)
img.run()

 

 

 

 

 

相關文章