python多線程爬取壁紙 媽媽再也(yě)不(bù)擔心我沒壁紙了(le/liǎo)! - 新聞資訊 - 雲南小程序開發|雲南軟件開發|雲南網站建設-昆明融晨信息技術有限公司

159-8711-8523

雲南網建設/小程序開發/軟件開發

知識

不(bù)管是(shì)網站,軟件還是(shì)小程序,都要(yào / yāo)直接或間接能爲(wéi / wèi)您産生價值,我們在(zài)追求其視覺表現的(de)同時(shí),更側重于(yú)功能的(de)便捷,營銷的(de)便利,運營的(de)高效,讓網站成爲(wéi / wèi)營銷工具,讓軟件能切實提升企業内部管理水平和(hé / huò)效率。優秀的(de)程序爲(wéi / wèi)後期升級提供便捷的(de)支持!

您當前位置>首頁 » 新聞資訊 » 技術分享 >

python多線程爬取壁紙 媽媽再也(yě)不(bù)擔心我沒壁紙了(le/liǎo)!

發表時(shí)間:2020-10-19

發布人(rén):融晨科技

浏覽次數:82

基于(yú)上(shàng)次的(de)簡單爬蟲之(zhī)後,這(zhè)次的(de)爬蟲添加了(le/liǎo)多線程的(de)新元素,使爬取的(de)速度在(zài)原來(lái)的(de)基礎上(shàng)快了(le/liǎo)N倍,話不(bù)多說(shuō),來(lái)看代碼
首先我們選擇的(de)網站還是(shì)上(shàng)次的(de)H128壁紙,不(bù)知道(dào)具體流程的(de)可以(yǐ)看下上(shàng)次寫的(de)入門代碼
傳送門!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
打開網站,這(zhè)裏我選擇的(de)是(shì)動漫專區的(de)壁紙,我們的(de)目的(de)是(shì)把所有動漫壁紙爬下來(lái),我們發現一共有98頁圖片
在(zài)這(zhè)裏插入圖片描述

所以(yǐ)我們要(yào / yāo)做的(de)是(shì)觀察每頁圖片鏈接的(de)關系,我們打開第二頁圖片觀察
發現兩頁圖片的(de)鏈接分别是(shì)
https://www.h128.com/pc/anime/0/2/1920x1080/t/1.html
https://www.h128.com/pc/anime/0/2/1920x1080/t/2.html

我們發現兩個(gè)網頁隻有t/後面的(de)數據不(bù)同由此我們觀察後面幾頁,最終我們發現/t/後面的(de)數字就(jiù)是(shì)代表頁數,所以(yǐ)在(zài)最開始我們建立一個(gè)函數來(lái)存放我們需要(yào / yāo)的(de)網頁鏈接
如下:

page_links_list = ['https://www.h128.com/pc/anime/0/2/1920x1080/t/1.html']
def GetUrls(page_links_list):
    pages = int(input("請輸入你想爬取的(de)頁數:"))
    if pages > 1:
        for page in range(2, pages + 1):
            url = 'https://www.h128.com/pc/anime/0/2/1920x1080/t/' + str(page) + '.html'
            page_links_list.append(url)
    else:
        page_links_list = page_links_list

然後就(jiù)是(shì)我們多線程的(de)應用了(le/liǎo),我們要(yào / yāo)用的(de)是(shì)python的(de)threading模塊首先需要(yào / yāo)導入threading

import threading

首先建立一個(gè)glock 用來(lái)控制

gLock = threading.Lock()

**threading 提供了(le/liǎo) Lock 類,該類能夠在(zài)某個(gè)線程訪問某個(gè)變量的(de)時(shí)候對變量加鎖,此時(shí)其它線程就(jiù)不(bù)能訪問該變量,直到(dào)該 Lock 被釋放其它線程才能夠訪問該變量
**
我們爬蟲需要(yào / yāo)生産者進程和(hé / huò)消費者進程,生産者的(de)線程專門用來(lái)生産一些數據,然後存放到(dào)一個(gè)中間的(de)變量中。消費者再從這(zhè)個(gè)中間的(de)變量中取出(chū)數據進行消費。但是(shì)因爲(wéi / wèi)要(yào / yāo)使用中間變量,中間變量經常是(shì)一些全局變量,因此需要(yào / yāo)使用鎖來(lái)保證數據完整性。在(zài)這(zhè)個(gè)代碼中生産者進程負責來(lái)獲取我們圖片的(de)url,而(ér)消費者進程的(de)目的(de)是(shì)下載圖片。
生産者代碼如下:

class Generant(threading.Thread):
    def run(self):
        while len(page_links_list) > 0:
            gLock.acquire()  #上(shàng)鎖
            page_url = page_links_list.pop()
            gLock.release() #釋放鎖
            r = requests.get(page_url,headers = headers)
            r.raise_for_status()
            r.encoding = r.apparent_encoding
            a = re.findall('<img src="https:(.*?)" alt',r.text)
            gLock.acquire() #上(shàng)鎖
            for i in a :
                x = 'https:' + i
                x = x.replace('w_487', 'w_1421').replace('h_274', 'h_799')
                img_links_list.append(x)
            gLock.release() #釋放鎖

消費者代碼如下

class Consumer(threading.Thread,):
    def run(self):
        while True:
            gLock.acquire()
            if len(img_links_list) == 0:
                gLock.release()
                continue
            else:
                img_url = img_links_list.pop()
                gLock.release()
                filename = img_url.split('?')[0].split('/')[-1]
                r = requests.get(img_url)
                print('正在(zài)下載:', filename)
                path = './picture/' + filename
                with open(path,'wb') as f:
                    f.write(r.content)
                    f.close()
                if len(img_links_list) == 0:
                    end = time.time()
                    print("消耗的(de)時(shí)間爲(wéi / wèi):", (end - start))
                    exit()

最後的(de)代碼就(jiù)是(shì)啓動線程

    for x in range(5):
        Generant().start()
    for x in range(5):
        Consumer().start()

觀看運行結果:

在(zài)這(zhè)裏插入圖片描述
這(zhè)裏是(shì)下載了(le/liǎo)50頁圖片的(de)時(shí)間,比起單線程還是(shì)很快的(de)。
在(zài)這(zhè)裏插入圖片描述
最後附上(shàng)完整代碼
下面展示一些 内聯代碼片

import threading
import requests
import re
import  time
import  os
page_links_list = ['https://www.h128.com/pc/anime/0/2/1920x1080/t/1.html']
img_links_list = []
headers = {
        "user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36"
}
def GetUrls(page_links_list):
    pages = int(input("請輸入你想爬取的(de)頁數:"))
    if pages > 1:
        for page in range(2, pages + 1):
            url = 'https://www.h128.com/pc/anime/0/2/1920x1080/t/' + str(page) + '.html'
            page_links_list.append(url)
    else:
        page_links_list = page_links_list
gLock = threading.Lock()
class Generant(threading.Thread):
    def run(self):
        while len(page_links_list) > 0:
            gLock.acquire()  #上(shàng)鎖
            page_url = page_links_list.pop()
            gLock.release() #釋放鎖
            r = requests.get(page_url,headers = headers)
            r.raise_for_status()
            r.encoding = r.apparent_encoding
            a = re.findall('<img src="https:(.*?)" alt',r.text)
            gLock.acquire() #上(shàng)鎖
            for i in a :
                x = 'https:' + i
                x = x.replace('w_487', 'w_1421').replace('h_274', 'h_799')
                img_links_list.append(x)
            gLock.release() #釋放鎖
class Consumer(threading.Thread,):
    def run(self):
        while True:
            gLock.acquire()
            if len(img_links_list) == 0:
                gLock.release()
                continue
            else:
                img_url = img_links_list.pop()
                gLock.release()
                filename = img_url.split('?')[0].split('/')[-1]
                r = requests.get(img_url)
                print('正在(zài)下載:', filename)
                path = './picture/' + filename
                with open(path,'wb') as f:
                    f.write(r.content)
                    f.close()
                if len(img_links_list) == 0:
                    end = time.time()
                    print("消耗的(de)時(shí)間爲(wéi / wèi):", (end - start))
                    exit()
if __name__ == '__main__':
    GetUrls(page_links_list)
    if os.path.exists('./picture'):
        print("文件已存在(zài)")
    else:
        os.mkdir('./picture')
    start = time.time()
    for x in range(5):
        Generant().start()
    for x in range(5):
        Consumer().start()

最後如果想要(yào / yāo)全站的(de)圖片隻要(yào / yāo)把鏈接改一下就(jiù)OK

相關案例查看更多