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

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

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

qq音乐

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

image-20191110145947495.png
image-20191110145947495.png

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

image-20191110150232596.png
image-20191110150232596.png

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

image-20191110150501484.png
image-20191110150501484.png

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

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,很容易处理

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

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库来处理

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库来对比歌曲名的相似程度

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)

将结果写入文件

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

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

添加新评论

评论列表