1. 程式人生 > >爬蟲網易雲音樂,熱評,詞雲,prettytable。

爬蟲網易雲音樂,熱評,詞雲,prettytable。

樂爬網易雲

你好!此篇文章是我的python課程的期末專案,主要功能有兩個,第一個是爬取網易雲音樂指定歌曲的熱門評論,並將其製作成詞雲,其次的一個功能是爬取網易雲音樂的動態排行榜,並以表格的形式展示。

熱門評論

第三方庫

直接爬網易雲的話,網站會自動反爬,獲取不到有用的資料,所以我採用的是呼叫api,獲取json資料,再解析。其中需要用到的庫有json,requests。
首先需要安裝用到的第三方庫。

pip3 install json
pip3 install requests

api介面

需要用到的api介面:

搜尋api:
http://music.163.com/api/search/get/web?csrf_token=hlpretag=&hlposttag=&s={}&type=1&offset=0&total=true&limit=5


第一個{}是你要搜尋的歌曲名,limit是你要搜尋的資訊條數,這裡我設定的是5條。

評論api:
http://music.163.com/api/v1/resource/comments/R_SO_4_{}
R_SO_4_後面的引數是歌曲的id,從搜尋的api中可以獲取。


對於爬取熱門評論,我的思路是以下:

  1. 首先呼叫搜尋的api,獲取到前五首歌的id。
  2. 其次呼叫評論的api,將搜尋獲得的歌曲id放到api中進行查詢。
  3. 最後解析獲取的json資料,並以一定的格式顯示出來。

獲取評論

準備工作做完了,就可以開始了!

url =
"http://music.163.com/api/search/get/web?csrf_token=hlpretag=&hlposttag=&s={}&type=1&offset=0&total=true&limit=5".format(name) #name是你搜索的歌曲名 headers = { 'Referer':'https://music.163.com/', "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36"} r2 = requests.get(url, headers=headers) r2.encoding="utf-8"

解析資料

這樣就可以獲取到你想搜尋的歌曲了,再通過解析json資料就能獲取到歌曲id。再以同樣的方式去獲取每一首歌曲id的熱門評論,再解析json資料。對於json資料解析,主要就是json.loads()和json.dumps()方法,這裡不做詳細說明了。

顯示資料

最後獲取到的所有的評論,全部在終端輸出(如下圖所示),並儲存在一個txt的檔案中,方便後續製作詞雲使用。在這裡我設定了一下終端輸出的字型顏色,使用方法很簡單,但是格式看起來有點麻煩:

開頭部分:\033[顯示方式;前景色;背景色m + 結尾部分:\033[0m
\033[0;34;mABC\033[0m
這樣輸出來的ABC就是藍色的

熱門評論
同時還將所有獲取到的熱門評論寫進一個檔案中comments.txt

詞雲

第三方庫

製作詞雲,首先我們要先安裝詞雲的第三方庫WordCloud

pip3 install WordCloud

如果要將詞雲製作成指定形狀的話,還需要安裝PIL.Image庫和numpy
如果是中文,還需要用jieba庫分詞

製作流程

1、讀取前面我們放評論的comments.txt的檔案
2、如果是中文的話,用jieba庫分詞
3、開啟一張你要繪製的圖形的圖片
4、生成詞雲

詞雲程式碼

with open(filename, 'r', encoding="utf-8") as f2:
    chiText = f2.read()
    word_list = jieba.cut(chiText)
    wcResult = " ".join(word_list)
    mask = np.array(Image.open("path"))
    wordCloud = WordCloud(font_path = 'simsun.ttc',width = 1500,height = 1000,\
                        background_color = 'white', mask=mask).generate(wcResult)
    image_produce = wordCloud.to_image()
    image_produce.show()

這裡特別需要注意的一點是,font_path是給詞雲指定的字型,這裡的引數是你安裝python環境是安裝的語言包,如果你沒有安裝,就會報錯。具體的安裝方法非常簡單,可以百度。

詞雲

我這裡用的是一張愛心形狀的圖片。詞雲的背景色,字型等都是可以具體設定的。
詞雲

排行榜

api

http://music.163.com/api/playlist/detail?id=19723756
id後面的引數是你要查詢的排行榜的id,例如雲音樂飆升榜的id是19723756,這個在網易雲的官網上可以查到。

PrettyTable

安裝

pip3 install PrettyTable

方法

.add_row():按行新增
.add_column():按列新增
.set_style(pt.PLAIN_COLUMNS):設定表格的風格

程式碼

table = pt.PrettyTable()
table.set_style(pt.PLAIN_COLUMNS)
table.add_row([y, songName, artistName, albumName])
print(table)

表格

表格

全部程式碼

from bs4 import BeautifulSoup
import requests,json,jieba,urllib
from wordcloud import WordCloud
import PIL.Image as Image
import numpy as np
import prettytable as pt
def songs():
    name = input("請輸入你想檢視的歌名:")
    url = "http://music.163.com/api/search/get/web?csrf_token=hlpretag=&hlposttag=&s={}&type=1&offset=0&total=true&limit=5".format(name)
    headers = {
        'Referer':'https://music.163.com/',
        "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36"}
    r2 = requests.get(url, headers=headers)
    r2.encoding="utf-8"
    filename = "comments.txt"
    search_result = json.loads(r2.text)['result']
    searchResult = json.dumps(search_result)
    search_songs = json.loads(searchResult)['songs']
    i = 0
    with open(filename, 'w', encoding="utf-8") as f:
        for searchSong in search_songs:
            i+=1
            song_id = searchSong.get("id")
            commUrl = "http://music.163.com/api/v1/resource/comments/R_SO_4_{}".format(song_id)
            r = requests.get(commUrl, headers=headers)
            r.encoding="utf-8"
            result = json.loads(r.text)['hotComments']
            contents = json.dumps(result)
            comms = json.loads(contents)
            print("精彩評論{}:".format(i))
            for comm in comms:
                content = json.dumps(comm)
                hotComments= json.loads(content)['content']
                user = json.loads(content)['user']
                userD = json.dumps(user)
                nickName = json.loads(userD)['nickname']
                print("\033[0;34;m{}\033[0m : [{}]\n".format(nickName, hotComments))
                f.write(hotComments+"\n")
    wc = input("是否生成詞雲?\n")
    with open(filename, 'r', encoding="utf-8") as f2:
        if wc.__eq__("是"):
            chiText = f2.read()
            word_list = jieba.cut(chiText)
            wcResult = " ".join(word_list)
            mask = np.array(Image.open("C:\Python\code\music163\heart.png"))
            wordCloud = WordCloud(font_path = 'simsun.ttc',width = 1500,height = 1000,\
                                background_color = 'white', mask=mask).generate(wcResult)
            image_produce = wordCloud.to_image()
            image_produce.show()
        else:
            return

def recommendation():
    listIdstr = input("您想檢視哪個榜單:\n1、雲音樂飆升榜 2、雲音樂新歌榜 3、網易原創歌曲榜 4、雲音樂熱歌榜"
                      " 5、江小白YOLO雲音樂說唱榜\n")
    listId=eval(listIdstr)
    if listId==1:
        ids = 19723756
    elif listId==2:
        ids=3779629
    elif listId==3:
        ids=2884035
    elif listId==4:
        ids=3778678
    elif listId==5:
        ids=991319590
    headers = {
        'Referer':'https://music.163.com/',
        "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKilt/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36"}
    url = "http://music.163.com/api/playlist/detail?id={}".format(ids)
    r = requests.get(url, headers=headers)
    r.encoding='utf-8'
    table = pt.PrettyTable()
    table.set_style(pt.PLAIN_COLUMNS)
    table.field_names=['序號','歌名', '歌手', '專輯']
    result=json.loads(r.text)['result']
    resultD=json.dumps(result)
    tracks=json.loads(resultD)['tracks']
    y=1
    x=1
    for track in tracks:
        tracksD=json.dumps(track)
        songName=json.loads(tracksD)['name']
        artists=json.loads(tracksD)['artists']
        for artist in artists:
            artistD=json.dumps(artist)
            artistName=json.loads(artistD)['name']
            if x==2:
                break
            x+=1
        album=json.loads(tracksD)['album']
        albumD=json.dumps(album)
        albumName=json.loads(albumD)['name']
        table.add_row([y, songName, artistName, albumName])
        y+=1
        if y==101:
            break
    print(table)

def main():
    num = eval(input("請輸入你想進行操作的編號:\n1、檢視歌曲熱評 2、檢視熱門推薦 \n"))
    if num == 1:
        songs()
    elif num==2:
        recommendation()
main()