爬虫网易云歌曲和对应的多个标签

1. 目的

得到所有歌曲及其对应的多个标签,返回JSON格式。

部分结果

2. 做法

  1. 爬取网易云所有歌单的id
  2. 利用网易云JSON格式的API接口得到对应歌单的信息
  3. 从信息中抽取歌单中歌曲名字和对应标签
  4. 整合歌曲标签并去重
  5. 以JSON格式输出

3. 问题和解决

第一步:爬取所有id

1.不会翻页

解决1:直接用selenium(但是由于是模拟浏览器太慢了,一个类别的歌单共38页左右,获得每类歌曲的全部歌单需要5分钟)(但其实还是selenium顺手,能看见界面真舒服啊)

解决2:通过limit和offset来控制参数limit是一页的歌单数量,offset在上一页的基础上加上即可。
(这个是从网页链接的层面解决的,不过话说我用这个爬到的少呢)

2.代码无误却得到不到东西

解决:查看框架源代码里面没有‘#’,但是网页登录会自动补上

self.start_url = "https://music.163.com/discover/playlist/"

3.id不都是10位数

解决:Python太差,用C++过一遍所有id去掉前面的‘=’

这里回想了一下文件读写操作,发现脑子里已经没有这些了....
C++写法查了些资料,这个还不错,虽然不太好看。( ,,´・ω・)ノ"(´っω・`。)
Python写法这个是python的写法~

第二步:爬虫JSON文件

1.爬取信息

API得到的便是JSON格式

API的接口网址是:http://music.163.com/api/playlist/detail?id=" + id”

JSON其实是一种很规矩的数据形式

JSON举例

这就是一张歌单的API得到的JSON的一部分,我需要的就是result中“tracks”里面的“name"

#把爬取到的json格式的网页转换成字典格式
res = requests.get(url).json()   
# 获取内容信息
num_tags = len(res.get("result")["tracks"])
for i in range(num_tags):
   print(res.get("result")["tracks"][i].get("name"))
   print(res.get("result")["tags"])

这样就可以在一大堆数据中找到名字和对应标签了~

2.“TypeError: 'NoneType' object is not subscriptable”

遇到这句错误,但是时而出现时而没有,太奇怪了...后来发现有些歌单是空歌单或是因为没有返回值,于是res.get("result")["tracks"]就是空值。

res = requests.get(url).json()   
    # 添上这两句就好了
    if res.get("result") != None:
        if res.get("result")["tracks"] != None:

第三步:获取对应关系

这个在第二步就得到了,就是如果会写断点就好了,我因为Colab中断而且没有断点需要重新获取,哎。

第四步:去重

在C++里写比较方便,直接用STL就好了

map<string,vector<string>>

第五步:以JSON格式输出

ans = []
....
for i in range(num_tags):
   music = {'name': res.get("result")["tracks"][i].get("name"), 'tags': res.get("result")["tags"]}
   ans.append(music)
json_str=json.dumps(ans)
# print(type(json_str))
print(json_str)

这样就将结果以JSON格式输出了~

4. 结果和总结

其一是会selenium爬虫了,虽然因为时间长最后没用,学的也很表面,但是我对这种无所畏惧的爬虫还行好好奇哇!

其二是见识到了网易云API,虽然还要爬虫获取JSON格式的信息

其三是程序中文件的读写,其实平时做题并不常用文件,都是直接CV...

最后是JSON的获取和存储。

刚刚终于爬完了所有歌曲,我给班长交了个没去重版嘿嘿嘿看看他能不能发现~

去看了一下结果...好像爬的不太行啊,似乎少了很多歌曲。。。

Last modification:August 10th, 2020 at 11:24 pm
请赏我杯奶茶,让我快乐长肉