爬蟲:一個簡單的數據爬取統計實例

原文地址

分類目錄——爬蟲

——自寫程序統計自己的CSDN博客訪問量

我的個人主頁

首先解析一下我的個人主頁

  • 要獲得全部博客,頁碼

    進入個人主頁之後顯示的我的博客第1頁,如果只分析一頁的,只需傳入這個網址就行了,要分析另外幾頁呢,要每次自己修改網址麼,我不想那麼幹

    看一下第2頁的網址

    https://blog.csdn.net/BBJG_001/article/list/2
    

    第3頁的

    https://blog.csdn.net/BBJG_001/article/list/3
    

    雖然第1頁的網址默認是https://blog.csdn.net/BBJG_001,但是當我這樣寫時

    https://blog.csdn.net/BBJG_001/article/list/1
    

    響應的網頁也確實是第1頁,那麼我就發現了規律,這些頁數只是最後的數字不同罷了,那麼我可以這麼寫了

    baseurl = 'https://blog.csdn.net/BBJG_001/article/list/'
    for i in range(1, lastpage):
        currenturl = baseurl + str(i)
        res = requests.get(currenturl)
        '''處理過程'''
    

    我見過的很多分頁的網站都有這種規律

    那麼另一個問題又來了,how can I get the lastpage,這得向網頁中去找答案

    進入網頁,通過F12 或 Ctrl+Shift+I 或 網頁上右擊 =》檢查 打開網頁檢查工具,選擇在Elements選項卡,在htmls源碼上移動鼠標,左邊會發生響應的反應,這樣可以輕鬆的找到某些部分的源碼所在

    1583073642674

    我本來打算通過解析html頁面獲取最後一頁,但是失敗了,這裏好像是動態生成的,根據用戶的實際博文數量動態生成頁碼,但是後來在一對script中發現了這些數據

    1583141855716

    這個就不能用BeautifulSoup來獲得了,我用正則表達式進行了屬性提取

    match = re.search(r'pageSize = (\d+).+\n.+listTotal = (\d+)', r0.text, flags=re.M)
        pageSize = match.group(1)
        listTotal = match.group(2)
    

    然後拼接每頁的url

    baseurl = 'https://blog.csdn.net/BBJG_001/article/list/'
    pages = int(listTotal)//int(pageSize)+1
    for i in range(1,pages+1):
        url = baseurl+str(i)
    
  • 解析網頁

    然後分析我的博客列表中的一頁

    1583146201104

    先獲取改網頁對象

    res = requests.get(url)
    soup = BeautifulSoup(res.text, 'html.parser')
    

    一個博客項包含在一個class=article-item-box csdn-tracking-statistics的div下,獲得所有的這樣的div列表

    divs = soup.find_all(name='div', attrs={'class': 'article-item-box csdn-tracking-statistics'})
    

    遍歷上面的div列表從每個div中取出a標籤組成一個a標籤的列表

    aas = [div.find('a') for div in divs]  # 獲得包含文章鏈接的a標籤
    

    遍歷上面的div列表從每個div中取出包含閱讀數的span標籤組成一個span標籤的列表

    spans = [div.find(name='span', attrs={'class': 'num'}) for div in divs]  # 獲得包含閱讀量的span
    

    分別從a列表中提取href、從span列表中提取數字,組成{href : num}的字典

    data = {a.attrs.get('href'): int(span.text) for a, span in zip(aas, spans)}
    
  • 數據處理

    print('最受歡迎的文章:', max(alldata, key=alldata.get))    # 返回字典中最大值對應的key
    # 最受歡迎的文章: https://blog.csdn.net/BBJG_001/article/details/104189333
    plt.bar(range(len(alldata)), list(alldata.values()))    # 柱狀圖
    plt.ylim(0, 250)  # 爲了不使結果看着太過懸殊,限制y軸高度
    plt.show()
    

    出圖如下

    1583146749757
  • 完整代碼

    import requests
    from bs4 import BeautifulSoup  # 解析html網頁的
    import re
    import matplotlib.pyplot as plt
    
    
    def getaPageData(url):
        res = requests.get(url)
        soup = BeautifulSoup(res.text, 'html.parser')
        divs = soup.find_all(name='div', attrs={'class': 'article-item-box csdn-tracking-statistics'})
        aas = [div.find('a') for div in divs]  # 獲得包含文章鏈接的a標籤
        spans = [div.find(name='span', attrs={'class': 'num'}) for div in divs]  # 獲得包含閱讀量的span
        return {a.attrs.get('href'): int(span.text) for a, span in zip(aas, spans)}  # 封裝成字典返回
    
    
    if __name__ == '__main__':
        indexurl = 'https://blog.csdn.net/BBJG_001'
        baseurl = 'https://blog.csdn.net/BBJG_001/article/list/'
        r0 = requests.get(indexurl)
        alldata = {}
    
        match = re.search(r'pageSize = (\d+).+\n.+listTotal = (\d+)', r0.text, flags=re.M)
        pageSize = match.group(1)  # 40
        listTotal = match.group(2)  # 152
        pages = int(listTotal) // int(pageSize) + 1
        for i in range(1, pages + 1):
            url = baseurl + str(i)
            datai = getaPageData(url)
            alldata.update(datai)  # 向alldata中追加本輪url的數據
    
        print('最受歡迎的文章:', max(alldata, key=alldata.get))  # 返回字典中最大值對應的key
    
        plt.bar(range(len(alldata)), list(alldata.values()))  # 柱狀圖
    
        plt.ylim(0, 250)  # 爲了不使結果看着太過懸殊,限制y軸高度
    
        plt.show()
    
  • 相關參考

    分類目錄——Matplotlib

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