kelovp.
首页 API [网易云音乐] 热评的故事。

[网易云音乐] 热评的故事。

在这次之前学习API的时候发现了一些事情,我利用网易云音乐的API实现了一些简单的歌曲搜索、封面图片的爬去之类的无聊事情。而最近在使用网易云的时候发现自己已经使用网易云整整两年了(顺便思考了一下我的手机为什么装一个APP这么久。连原来的QQ都被卸载了,而网易云依旧在)自己在这两年里成长了许多。而之前在16年初的时候网易云曾针对每一个用户做出一个数据报表:其中包括了播放量TOP10和听歌最久日,最晚听歌使时间和日单循环次数、点赞次数这些东西,当时这个报表其实挺受大家欢迎,而更多的是网易云特有的评论区环境,使用网易云音乐的人大多都是90后,00后。庆幸的是云音乐的讨论区没有成为贴吧知乎那样的气候。但是究竟是怎样的评论吸引着我们这些年轻对着一个 APP放不下手?(不谈音乐,怕大手子 2333),所以就本着这样的目的我尝试去做了:

    开始征程吧:

    在这之前我有写过关于API的一点东西:API简介和网易云音乐API 其中有提到一些简单的处理办法。而面对大批量的歌曲(目前我听了5800首)这样的方法早已失去其使用的价值和理由,所以得采取新的办法。在这之前我得理清一些东西:首先网易云获取用户听歌量肯定离不开用户ID。而评论的获取则之和歌曲id有关。

从歌单开始:

    首先我参考了一下别人写的自用性的文档:https://github.com/darknessomi/musicbox/blob/master/

    因为是我听过的歌曲:我现在的歌单数目27个。外加收藏的歌单37个 所以:http://music.163.com/api/user/playlist/?offset=0&limit=64&uid=我的id 

    这样一来我就拿到了我所有的歌单。现在要做的就是拿到这些歌单中所有的歌曲id。

    

    干这件是之前要做的就是:解析json,拿到list的id号。

# coding=utf-8 import json from urllib import urlopen, quote
url = ”http://music.163.com/api/user/playlist/?offset=0&limit=64&uid=97752165” res = urlopen(url).read().decode(”utf-8”) temp = json.loads(res) lengs = len(temp.get(“playlist”)) ids = [] for i in range(0,lengs):
ids.append(temp.get(“playlist”)[i].get(“id”)) print(ids)

    这样我就将所有歌单的id存入了ids列表当中,而接下来就是将列表当中的歌曲id和歌曲name获取。

    http://music.163.com/api/playlist/detail?id=歌单id 这样一来我就拿到了所有的歌曲:

    依旧是处理json数据。

musicid = [] musicname = [] url = ”http://music.163.com/api/playlist/detail?id=” for i in findUserlist():
res = urlopen(url+str(i)).read().decode(”utf-8”)
temp = json.loads(res)
lengs = len(temp.get(“result”).get(“tracks”))
for j in range(0,lengs):
musicid.append(temp.get(“result”).get(“tracks”)[j].get(“id”)) musicname.append(temp.get(“result”).get(“tracks”)[j].get(“name”)) print(musicname) print(musicid)

    拿到了所有歌曲的id和name(其实只要id就好我,我只是采集评论。name的话用不着的)下一步就是最重要的几部了

获取评论

    来到这一步之后我要做的事情就是将所有歌曲的id挨个遍历,查看评论,依旧是解析 json,然后存入数据库当中,最终程序如下:

# coding=utf-8 import json from urllib import urlopen, quote import pymysql

conn = pymysql.connect(host=”localhost”,user=”root”, passwd=”******”, db=”nestmusic”,charset=“utf8”) cur = conn.cursor() cur.execute(“USE nestmusic”) def store(title, content):
cur.execute(“INSERT INTO comment (musicname, hotcoment) VALUES (\\“%s\\”,\\“%s\\”)”, (title, content)) cur.connection.commit() def findUserlist():
url = ‘http://music.163.com/api/user/playlist/?offset=0&limit=64&uid=97752165
res = urlopen(url).read().decode(”utf-8”)
temp = json.loads(res)
lengs = len(temp.get(“playlist”))
ids = []
for i in range(0,lengs):
ids.append(temp.get(“playlist”)[i].get(“id”))
return ids
def findMusiclist():
musicid = []
musicname = []
url = ”http://music.163.com/api/playlist/detail?id=
for i in findUserlist():
res = urlopen(url+str(i)).read().decode(”utf-8”)
temp = json.loads(res)
lengs = len(temp.get(“result”).get(“tracks”))
for j in range(0,lengs):
musicid.append(temp.get(“result”).get(“tracks”)[j].get(“id”)) musicname.append(temp.get(“result”).get(“tracks”)[j].get(“name”))
return musicid,musicname def inDb():
url = ‘http://music.163.com/api/v1/resource/comments/R\_SO\_4\_‘
for i in findMusiclist()[0]:
res = urlopen(url+str(i)+”/?rid=R_SO_4_”+str(i)+”&\\offset=0&total=fasle&limit=100”).read().decode(”utf-8”) temp = json.loads(res)
print(temp.get(“hotComments”)[0].get(“content”))
lengs = len(temp.get(“hotComments”))
for j in range(0,lengs):
store(findMusiclist()[1].pop(), temp.get(“hotComments”)[j].get(“content”)) try:
inDb() finally:
cur.close()
conn.close()

   因为有API访问次数的限制,好像一次采集不完:

    但是我不会这样轻易的狗带(滑稽) 而上面的程序依旧存在着巨大的问题,入库其实是无法运行的,由于没有设定请求头的缘故导致很多请求被视为作弊请求,状态码是460,所以我测试了一下单独用浏览器请求发现不受限制:哈哈哈哈

    这样一来 一定程度解决了一些问题,但是次数还是不能太频繁,应该是服务器端有次数限制-。而这里最终我把数据处理之后保存为cvs,初级处理也就做完了。

head = {‘Host’:‘music.163.com’, ‘User-Agent’:‘Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0’, ‘Accept’: ‘text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8’, ‘Accept-Language’: ‘zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3’, ‘Accept-Encoding’:‘deflate’,‘Connection’: ‘keep-alive’, ‘Upgrade-Insecure-Requests’ : ‘1’, ‘Cache-Control’:‘max-age=0’ } url = ‘http://music.163.com/api/v1/resource/comments/R\_SO\_4\_’ for i in musicId:
uri = url + str(i)+’/?rid=R_SO_4_‘+str(i)+’&\\offset=0&total=fasle&limit=100’
req = urllib2.Request(uri, None, head)
res = urllib2.urlopen(req).read()

K
kelovp
后端工程师 · 广告投放 / 商业化
八年后端,做广告投放与商业化变现系统,现在带团队折腾商业化中台与 AIGC 内容平台。工作之外写点电子音乐、动漫解析和故事。相信把事情想清楚,才写得明白。