【新手必學】Python爬蟲之多線程實戰


1.先附上沒有用多線程的包圖網爬蟲的代碼

 import requests安全

from lxml import etree import osimport time

start_time = time.time()#記錄開始時間
for i in range(1,7):
    #1.請求包圖網拿到總體數據
    response = requests.get("https://ibaotu.com/shipin/7-0-0-0-0-%s.html" %str(i))

    #2.抽取 視頻標題、視頻連接
    html = etree.HTML(response.text)
    tit_list = html.xpath('//span[@class="video-title"]/text()')#獲取視頻標題
    src_list = html.xpath('//div[@class="video-play"]/video/@src')#獲取視頻連接for tit,src in zip(tit_list,src_list):
        #3.下載視頻
        response = requests.get("http:" + src)
        #給視頻連接頭加上http頭,http快可是不必定安全,https安全可是慢

        #4.保存視頻
        if os.path.exists("video1") == False:#判斷是否有video這個文件夾
            os.mkdir("video1")#沒有的話建立video文件夾
        fileName = "video1\\" + tit + ".mp4"#保存在video文件夾下,用本身的標題命名,文件格式是mp4
                                            #有特殊字符的話須要用\來註釋它,\是特殊字符因此這裏要用2個\\
        print("正在保存視頻文件: " +fileName)#打印出來正在保存哪一個文件
        with open (fileName,"wb") as f:#將視頻寫入fileName命名的文件中
           f.write(response.content)end_time = time.time()#記錄結束時間 print("耗時%d秒"%(end_time-start_time))#輸出用了多少時間

2.將上述代碼套用多線程,先建立多線程markdown

data_list = []#設置一個全局變量的列表
# 建立多線程
class MyThread(threading.Thread):
    def __init__(self, q):
        threading.Thread.__init__(self)
        self.q = q

    #調用get_index()
    def run(self) -> None:
        self.get_index()

    #拿到網址後獲取所須要的數據並存入全局變量data_list中
    def get_index(self):
        url = self.q.get()
        try:
            resp = requests.get(url)# 訪問網址
            # 將返回的數據轉成lxml格式,以後使用xpath進行抓取
            html = etree.HTML(resp.content)
            tit_list = html.xpath('//span[@class="video-title"]/text()')  # 獲取視頻標題
            src_list = html.xpath('//div[@class="video-play"]/video/@src')  # 獲取視頻連接
            for tit, src in zip(tit_list, src_list):
                data_dict = {}#設置一個存放數據的字典
                data_dict['title'] = tit#往字典裏添加視頻標題
                data_dict['src'] = src#往字典裏添加視頻連接
                # print(data_dict)
                data_list.append(data_dict)#將這個字典添加到全局變量的列表中

        except Exception as e:
            # 若是訪問超時就打印錯誤信息,並將該條url放入隊列,防止出錯的url沒有爬取
            self.q.put(url)
            print(e)

3.用隊列queue,queue模塊主要是多線程,保證線程安全使用的網絡

def main():
    # 建立隊列存儲url
    q = queue.Queue()
    for i in range(1,6):

        # 將url的參數進行編碼後拼接到url
        url = 'https://ibaotu.com/shipin/7-0-0-0-0-%s.html'%str(i)
        # 將拼接好的url放入隊列中
        q.put(url)

    # 若是隊列不爲空,就繼續爬
    while not q.empty():
        # 建立3個線程
        ts = []
        for count in range(1,4):
            t = MyThread(q)
            ts.append(t)
        for t in ts:
            t.start()
        for t in ts:
            t.join()

4.建立存儲方法,若是你學習遇到問題找不到人解答,能夠點我進裙,裏面大佬解決問題及Python教.程下載和一羣上進的人一塊兒交流!多線程

#提取data_list的數據並保存
def save_index(data_list):
    if data_list:
        for i in data_list:
            # 下載視頻
            response = requests.get("http:" + i['src'])
            # 給視頻連接頭加上http頭,http快可是不安全,https安全可是慢

            # 保存視頻
            if os.path.exists("video") == False:  # 判斷是否有video這個文件夾
                os.mkdir("video")  # 沒有的話建立video文件夾
            fileName = "video\\" + i['title'] + ".mp4"  # 保存在video文件夾下,用本身的標題命名,文件格式是mp4
            # 有特殊字符的話須要用\來註釋它,\是特殊字符因此這裏要用2個\\
            print("正在保存視頻文件: " + fileName)  # 打印出來正在保存哪一個文件
            with open(fileName, "wb") as f:  # 將視頻寫入fileName命名的文件中
                f.write(response.content)

5.最後就是調用函數了app

if __name__ == '__main__':
    start_time = time.time()
    # 啓動爬蟲
    main()
    save_index(data_list)
    end_time = time.time()
    print("耗時%d"%(end_time-start_time))

6.附上完整的多線程代碼ide

import requests
from lxml import etree
import os
import queue
import threading
import time

data_list = []#設置一個全局變量的列表

# 建立多線程
class MyThread(threading.Thread):
    def __init__(self, q):
        threading.Thread.__init__(self)
        self.q = q

    #調用get_index()
    def run(self) -> None:
        self.get_index()

    #拿到網址後獲取所須要的數據並存入全局變量data_list中
    def get_index(self):
        url = self.q.get()
        try:
            resp = requests.get(url)# 訪問網址
            # 將返回的數據轉成lxml格式,以後使用xpath進行抓取
            html = etree.HTML(resp.content)
            tit_list = html.xpath('//span[@class="video-title"]/text()')  # 獲取視頻標題
            src_list = html.xpath('//div[@class="video-play"]/video/@src')  # 獲取視頻連接
            for tit, src in zip(tit_list, src_list):
                data_dict = {}#設置一個存放數據的字典
                data_dict['title'] = tit#往字典裏添加視頻標題
                data_dict['src'] = src#往字典裏添加視頻連接
                # print(data_dict)
                data_list.append(data_dict)#將這個字典添加到全局變量的列表中

        except Exception as e:
            # 若是訪問超時就打印錯誤信息,並將該條url放入隊列,防止出錯的url沒有爬取
            self.q.put(url)
            print(e)



def main():
    # 建立隊列存儲url
    q = queue.Queue()
    for i in range(1,7):

        # 將url的參數進行編碼後拼接到url
        url = 'https://ibaotu.com/shipin/7-0-0-0-0-%s.html'%str(i)
        # 將拼接好的url放入隊列中
        q.put(url)

    # 若是隊列不爲空,就繼續爬
    while not q.empty():
        # 建立3個線程
        ts = []
        for count in range(1,4):
            t = MyThread(q)
            ts.append(t)
        for t in ts:
            t.start()
        for t in ts:
            t.join()

#提取data_list的數據並保存
def save_index(data_list):
    if data_list:
        for i in data_list:
            # 下載視頻
            response = requests.get("http:" + i['src'])
            # 給視頻連接頭加上http頭,http快可是不安全,https安全可是慢

            # 保存視頻
            if os.path.exists("video") == False:  # 判斷是否有video這個文件夾
                os.mkdir("video")  # 沒有的話建立video文件夾
            fileName = "video\\" + i['title'] + ".mp4"  # 保存在video文件夾下,用本身的標題命名,文件格式是mp4
            # 有特殊字符的話須要用\來註釋它,\是特殊字符因此這裏要用2個\\
            print("正在保存視頻文件: " + fileName)  # 打印出來正在保存哪一個文件
            with open(fileName, "wb") as f:  # 將視頻寫入fileName命名的文件中
                f.write(response.content)

if __name__ == '__main__':
    start_time = time.time()
    # 啓動爬蟲
    main()
    save_index(data_list)
    end_time = time.time()
    print("耗時%d"%(end_time-start_time))

7.這2個爬蟲我都設置了開始時間和結束時間,能夠用(結束時間-開始時間)來計算比較二者的效率。
在這裏插入圖片描述
在這裏插入圖片描述函數

相關文章
相關標籤/搜索