爬虫网易云音乐,热评,词云,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",
    	"Cookie":"mail_psc_fingerprint=b67dc19b765cceeefdd9a96e81b67601; P_INFO=lysyun@126.com|1527329213|0|mail126|00&99|sic&1527328900&mail126#sic&510100#10#0#0|&0|mail126&unireg|lysyun@126.com; _iuqxldmzr_=32; _ntes_nnid=584cf3e825f3b7dae5e36de99b3291c8,1527329223818; _ntes_nuid=584cf3e825f3b7dae5e36de99b3291c8; __f_=1540186269377; WM_TID=8u9Q4qH2DeNARUBAERNsbjNfViydAnTb; JSESSIONID-WYYY=juOGS%2Fqr%5Cd9tHNbI%2FXFEp%5CK0sNwGmb0HkE11UpBDN8usBz7nQHlA%2FUO%5Cu%5CPPiJcRkk8rcbl12Yrp6615QgMo5jxXb1KtbzqO35DMP2u962IZ%2Bu8KDii7eYlY5MO%2F5snM2qbjgsxYKFDms12lwbAON%2FdYvFPSue%2BBW437Zf4%2Fi0qV%2FmQk%3A1545893338754; __utma=94650624.2014360837.1543287251.1545708495.1545891540.9; __utmc=94650624; __utmz=94650624.1545891540.9.6.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; __utmb=94650624.2.10.1545891540; WM_NI=PR8NgmlupCCzErrBcBpOrX7mGIeq8%2BNqBI9PMu%2F7SAeKC225MLyifKqMzMt8tMZBLTE%2BoXTs44gBGPh37LOmZnF7rXH5CJHrTN60CaSBIPndbkAwbP3DJXTItTMLOio%2BMUY%3D; WM_NIKE=9ca17ae2e6ffcda170e2e6eed2ed4290b8b99acf6ebb8e8bb3d45f979b9eabf35cb2eebdaaef54b4b0febab62af0fea7c3b92a948ef8afe667b0abc0a4c27287aebea3e24ab491beb9b6678597ab92bb218eaf8eaabc5c8fabe1d8d24ba7958dd3b13f8f94b78ae541b393b6aef734b89396a3cf6087f5a1b9d779f8eca9a3c65cacedf9adce679ab28ad8f1548ceb8dabcb7a9892fad1c26b919e87b1ed70a2b58f98e15cf19c86b9d743b88c83adce63adf583b6dc37e2a3"}
    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()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值