用Python进行网易云和qq音乐歌单对比

由于网易云音乐版权越来越少,歌单里的歌一首首的灰掉,于是就想着换到qq音乐。但是用qq音乐导入网易云的歌单后还是有一部分歌没有匹配到,而qq音乐也没告诉你哪些没匹配到,人工一个个筛选实在不现实,所以就想用代码来解决这个问题。

初步打算根据歌曲名来筛选,首先就要获取到这两家的歌单数据

qq音乐

首先登录到qq音乐的网页版,进入歌单页面,F12大法

可以看到歌曲信息是放在这样一个结构里的,然后查看网页源码却找不到这些内容,由此可见这些数据是动态加载的,要获取它们只能找到相应的接口,然后我找到了这个

应该是歌单的数据接口,换用postman请求

果然是歌单数据,songlist这个数组里应该就是所有的歌曲了,注意GET请求参数中的song_num参数,这个是返回的歌曲数量,把他改为歌单里歌曲总数就可以拿到所有歌曲信息了

1
2
3
4
5
6
7
8
9
10
11
12
13
header = {
'Referer': 'https://y.qq.com/',
'Accept': '*/*',
'Accept-Language': 'en-US,en;q=0.8',
'Cache-Control': 'max-age=0',
'User-Agent':
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36',
'Connection': 'keep-alive'
}

req = requests.get(
'https://c.y.qq.com/qzone/fcg-bin/fcg_ucc_getcdinfo_byids_cp.fcg?type=1&json=1&utf8=1&onlysong=0&new_format=1&disstid=774328000&g_tk=5381&loginUin=1271703270&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq.json&needNewCode=0&song_begin=0&song_num=446',
headers=header)

由于拿到的数据是json,很容易处理

1
2
3
4
5
6
7
obj = json.loads(req.text)

qqList = []

for song in obj['cdlist'][0]['songlist']:
qqList.append(
re.sub(u'(\\(.*?\\))|(\\(.*?\\))|(\\[.*?\\])', '', song['title'])

这里我用正则匹配去掉了所有的括号内容,提高之后筛选的精确度,所有歌曲的名称都存到了qqList这个列表里

网易云音乐

和qq音乐一样是动态加载,接口地址https://music.163.com/playlist?id=66699402id是歌单的id

1
2
3
4
5
6
7
8
9
10
11
12
header = {
'Referer': 'https://music.163.com/',
'Accept': '*/*',
'Accept-Language': 'en-US,en;q=0.8',
'Cache-Control': 'max-age=0',
'User-Agent':
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36',
'Connection': 'keep-alive'
}

req = requests.get('https://music.163.com/playlist?id=66699402',
headers=header)

由于返回数据是html文档,所以用Beautifulsoup库来处理

1
2
3
4
5
6
7
soup = BeautifulSoup(req.text, 'html.parser')
tag = soup.find("ul", attrs={'class': ['f-hide']})
neteaseList = []
for song in tag.children:
neteaseList.append(
re.sub(u'(\\(.*?\\))|(\\(.*?\\))|(\\[.*?\\])', '',
song.contents[0].text))

同样将歌曲名处理括号后保存在neteaseList列表里

数据分析

为了对比两个歌单,我打算用difflib库来对比歌曲名的相似程度

1
2
3
4
5
6
7
songList = set()
for s1 in neteaseList:
for s2 in qqList:
t = difflib.SequenceMatcher(None, s1, s2).ratio()
if t >= 0.6:
songList.add(s1)
results = set(neteaseList).difference(songList)

将结果写入文件

1
2
3
with open('list.txt', 'w', encoding='utf-8') as f:
for s in results:
f.writelines(s + '\n')

这样进行匹配精度不会太高,不过也勉强够用,可以适当调整t的值让输出的结果与丢失的歌曲数量差不多,这样就可以去手动搜索补全丢失的歌曲了,虽然也挺花时间,但是总比之前好多了

用Python进行网易云和qq音乐歌单对比

https://jktu.cc/用Python进行网易云和qq音乐歌单对比/

作者

udp_bbr

发布于

2019-12-09

更新于

2021-07-30

许可协议