【Python】【爬蟲】爬取酷狗TOP500


好啦好啦,那我們來拉開我們的爬蟲之旅吧~~~

這一只小爬蟲是爬取酷狗TOP500的,使用的爬取手法簡單粗暴,目的是幫大家初步窺探爬蟲長啥樣,后期會慢慢變得健壯起來的。

環境配置

在此之前需要下載一個谷歌瀏覽器,下好后由於谷歌搜索是需要FQ的,可設置打開網頁為百度來使用

我們用到的是bs4,要求這兩個庫來提取,這是簡稱,全稱是BeautifulSoup庫。中文名也叫“美麗的湯”,安裝也很簡單。

:cmd命令行(win + r),輸入pip install bs4完成安裝,如下圖:

bs4安裝.PNG

請求庫同樣,pip安裝請求

可能遇到的安裝錯誤

如果執行pip install bs4后報錯為“ pip不是重置的命令”

這是因為沒有把pip的路徑加入“環境變量”,加入環境變量即可

構造請求網址

我們是爬取酷狗音樂TOP500的'音樂名','歌手','歌名','播放時間'這幾個數據網址如下:

https://www.kugou.com/yy/rank/home/1-8888.html?from=rank

:后只能看到前22名的數據,如下:

第一頁數據顯示.PNG

網址也叫url,唯一資源定位符,我們觀察url如下幾個細分:

https:傳輸協議,一般都是http或https

www.kugou.com:為域名

yy / rank / home / abs:為域名下的子網頁

.html:代表此網頁是靜態的,后面會講

?:問號后面的一般都是一些請求參數

我們可以看到,其中有一個1-8888這個參數,打開上述網址后我們只能看到前22首歌,想繼續查看后面的歌曲就得翻頁,就像“淘寶”那樣查看下一頁商品需要翻頁,這里也是一樣的道理,把1-8888改成2-8888,就會看到下一頁的22首歌,如下:

第二頁數據.PNG

我們翻到第500首音樂那一頁,可以看到頁碼如下有23頁:

最后一頁.PNG

到這里我們我們需要提取的數據就知道在哪里了。

在知道了有多少頁以及url的含義后,通過以下代碼構造所有的url:

urls = ['https://www.kugou.com/yy/rank/home/{}-8888.html?from=rank'
                .format(str(i)) for i in range(1, 24)]

構造請求頭

什么是請求頭?

別人網頁區別是人還是機器訪問的一種手段,我們設置請求頭為瀏覽器的請求頭,對方就會認為我們是人為的訪問,從而不會反爬,當然這只是最簡單的一種防反爬的手段,一般我們都會帶上,代碼如下:

headers = {
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/53\
        7.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36'
    }

這並不是一個一個手敲的!!!

我們來看看它在哪里,按F12出現開發者工具,再按F5刷新出現如下圖:

f12.png

按照紅線提示,找到用戶代理

找header.PNG

最后復制粘貼得到上面的代碼

請求訪問網頁

response = requests.get(url, headers=headers)
if response.status_code == 200:
    return response.text
else:
    return

響應= request.get(URL,headers = headers)

使用請求庫的get方法,去訪問網頁,第一個參數為網址,第二個參數為請求頭,請求結果賦值給變量response,其中里面有很多結果,狀態響應碼,網頁二進制代碼,二進制等

response.status_code == 200

調用請求結果響應中的status_code查看請求狀態碼,200代表請求成功,就返回,否則返回一個None,狀態碼一般有2xx,4xx,3xx,5xx,分別代表請求成功,客戶端訪問失敗,重定向,服務器問題。

返回response.text

返回響應結果的text,代表返回網頁html源碼

解析網頁

在上面返回了一個響應后,我們需要解析網頁html源碼,需要結構化,可以提取

html = BeautifulSoup(html)

提取數據

我們來提取排名,鼠標放在排名這個元素這里,右鍵檢查:

快捷檢查.PNG

li:nth-​​child(1)需要改成li,因為nth-child(在右邊可以看到一串二進制。其中有個高兩個,就是剛剛那個排名的元素,快捷跟隨提示選擇然后復制過去,其中li:nth-​​child(1) 1)是獲取li標簽下的一條數據,我們是要獲取這一頁的所有排名

選擇排名.PNG

# 排名
ranks = html.select('#rankWrap > div.pc_temp_songlist > ul > li > span.pc_temp_num')

同樣的方法提取歌手歌名,播放時間

# 歌手 + 歌名
names = html.select('#rankWrap > div.pc_temp_songlist > ul > li > a')
# 播放時間
times = html.select('#rankWrap > div.pc_temp_songlist > ul > li > span.pc_temp_tips_r > span')

獲得數據

for r,n,t in zip(ranks,names,times):
        r = r.get_text().replace('\n','').replace('\t','').replace('\r','')
        n = n.get_text()
        t = t.get_text().replace('\n','').replace('\t','').replace('\r','')

用了zip函數,意思是把對應的排名,歌名歌手,播放時間打包,可以這樣理解zip函數的結果是一個列表[(排名,歌手歌名,播放時間),(排名,歌手歌名,播放時間)。。。。。]

每一次循環的r,n,t一次對應元組中的元素

get_text()

我們提取到的是這個數據所在的標簽信息,並不是實際數據,所以需要使用get_text()獲得實際數據

.replace('\ n','')。replace('\ t','')。replace('\ r','')

去掉實際數據中多余的字符串

最后把數據打包成字典打印

結束

到這里我們的關鍵步驟就完成了,大家好好理解一下,很容易的。

在這里說一下,這種提取方式是不會常見的,因為效果很不健壯,可能過幾天被人網頁改了改結構,就不能使用了,這里只是讓大家初步了解一下爬蟲的大致提取流程,后面會使用其他更健壯的方法的。

運行結果:

 

 

最終代碼

import requests
import time
from bs4 import BeautifulSoup


def get_html(url):
    '''
    獲得 HTML
    '''
    headers = {
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/53\
        7.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36'
    }
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
        return response.text
    else:
        return


def get_infos(html):
    '''
    提取數據
    '''
    html = BeautifulSoup(html)
    # 排名
    ranks = html.select('#rankWrap > div.pc_temp_songlist > ul > li > span.pc_temp_num')
    # 歌手 + 歌名
    names = html.select('#rankWrap > div.pc_temp_songlist > ul > li > a')
    # 播放時間
    times = html.select('#rankWrap > div.pc_temp_songlist > ul > li > span.pc_temp_tips_r > span')

    # 打印信息
    for r,n,t in zip(ranks,names,times):
        r = r.get_text().replace('\n','').replace('\t','').replace('\r','')
        n = n.get_text()
        t = t.get_text().replace('\n','').replace('\t','').replace('\r','')
        data = {
            '排名': r,
            '歌名-歌手': n,
            '播放時間': t
        }
        print(data)


def main():
    '''
    主接口
    '''
    urls = ['https://www.kugou.com/yy/rank/home/{}-8888.html?from=rank'
                .format(str(i)) for i in range(1, 24)]
    for url in urls:
        html = get_html(url)
        get_infos(html)
        time.sleep(1)


if __name__ == '__main__':
    main()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM