爬虫网易云音乐,热评,词云,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()

猜你喜欢

转载自blog.csdn.net/qq_42467823/article/details/85214394
今日推荐