多線程爬取小米商城應用信息

多線程爬取小米商城

前言:想必大家對python的多線程還不是很瞭解吧,今天我們的學習任務就是怎麼使用多線程去爬取小米商城的App應用

1. 分析目標站點
目標URL : http://app.mi.com/category/15#page=0 小米商城
點擊 “遊戲-全部應用” 下方的下一頁後發現整個頁面只刷新了部分內容,這就說明整個網頁都是動態加載來的,以下總結了怎麼去判斷整個網頁是不是動態加載的。

總結:

  • 鼠標往下滾動時加載了內容,但是整個頁面沒有重新加載
  • 當點擊下一頁或者往下翻滾的時候只刷新了網頁中的部分內容,整個頁面也沒有重新加載
  • 當在頁面中能找到的內容在網頁源代碼中找不到此內容時

小貼士:當碰到無法抓取的動態加載網頁時,推薦使用selenium,可以python的第三方庫中安裝,這個庫可以人爲的操作瀏覽器去做自己想要做的事情,當我們以瀏覽器去操作網頁時,我們也就不用考慮這個網頁是不是動態加載的了。

2. 分析加載的數據

a) 抓包。當確定網頁中的內容是動態異步加載時,我們第一個要做的抓包,右鍵檢查進入Network → XHR中,異步加載的數據一般都可以在這裏進行顯示
在這裏插入圖片描述
b) 分析url。觀察發送請求的url,發現只有page在變,而且第一頁中的page對應的值爲0,所以只需要改變page的值便可以獲取全部的內容了。
在這裏插入圖片描述
3.分析代碼
a) 創建請求url的隊列。今天我們的主要內容是怎麼去使用多線程爬取內容,所以我們第一步要做的就是怎麼去創建發送請求url的隊列。代碼如下

我們首先將要爬取的url加入到url _list這個隊列中去

class Xmshoop_spider(object):
    def __init__(self):
        self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36'}
        self.url = 'http://app.mi.com/categotyAllListApi?page={}&categoryId=15&pageSize=30'   # 需要爬取的url,通過改變page的值從而獲取所有需要發送請求的url
        self.url_list = Queue()    # 創建先進先出隊列

    def send_request(self):
        pass

    def parse_json(self):
        pass

    def main(self):
        for i in range(0,67):   # for循環
            self.url_list.put(self.url.format(i))   # 將要爬取的url通過put方法加入到隊列中
        
if __name__ == '__main__':
    spider = Xmshoop_spider()
    spider.main()

b) 發送請求獲取數據。通過隊列的get方法取出最先put進去的url,因爲我們創建的是先進先出隊列,所以我們get得到的就是第一個放進去的url。

取出第一個url併發送請求獲取數據

    def send_request(self):
        response = requests.get(self.url_list.get(),headers=self.headers).json()   # 通過get方法取出第一個放進去的url,然後將獲取到的json數據轉爲python中的字典類型數據
        print(response)

c)分析數據。獲取到數據後肯定就要提取出我們想要的數據,這裏我告訴大家兩種提取json數據的方法

  • 將獲取的json數據轉爲python中的字典類型,然後去提取
  • 使用jsonpath語法直接對json數據進行操作並提取數據

d) 多線程請求數據。

    def main(self):
        t_list = []
        for i in range(0,67):   # for循環
            self.url_list.put(self.url.format(i))   # 將要爬取的url通過put方法加入到隊列中
        
        for x in range(5):
            t1 = Thread(target=self.send_request) # target的值函數名
            t1.start()   # 啓動線程
            t_list.append(t1)   # 將線程加入到列表中
            
        for t in t_list:
            t.join()   # 讓主線程等待子線程結束

4. 完整代碼:

import requests
from threading import Thread
from queue import Queue

class Xmshoop_spider(object):
    def __init__(self):
        self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36'}
        self.url = 'http://app.mi.com/categotyAllListApi?page={}&categoryId=15&pageSize=30'   # 需要爬取的url,通過改變page的值從而獲取所有需要發送請求的url
        self.url_list = Queue()    # 創建先進先出隊列
        self.count = 0

    def send_request(self):
        while not self.url_list.empty():
            response = requests.get(self.url_list.get(),headers=self.headers).json()   # 通過get方法取出第一個放進去的url,然後將獲取到的json數據轉爲python中的字典類型數據
            self.parse_json(response)

    def parse_json(self,res):
        for data in res['data']:
            name = data['displayName']
            img_url = data['icon']
            print(name,img_url)
            self.count += 1


    def main(self):
        t_list = []
        for i in range(0,67):
            self.url_list.put(self.url.format(i))   # 將要爬取的url通過put方法加入到隊列中

        for x in range(5):   # for循環5次,總共創建了5個線程去爬取
            t1 = Thread(target=self.send_request)  # 創建線程
            t1.start()        # 啓動線程
            t_list.append(t1)

        for t in t_list:
            t.join()   # 主線程會一直阻塞等待子線程結束

if __name__ == '__main__':
    spider = Xmshoop_spider()
    spider.main()
    print(spider.count)  # 顯示總共爬取了多少個數據

a) 檢查結果。一頁30個應用信息,67頁正好2010條數據,對比開啓線程和不開啓線程爬取數據所花費的時間

  • 開啓10個線程花費1s
    在這裏插入圖片描述
  • 不開啓線程花費了10s

在這裏插入圖片描述

結語:本章的多線程學習就到這裏結束了,有覺得小編寫的還不錯的評論加點贊,你們的支持是我最大的動力。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章