美文网首页python爬虫大数据 爬虫Python AI SqlPython3自学 爬虫实战
从网易云音乐缓存文件得到 MP3 ,并爬取歌词

从网易云音乐缓存文件得到 MP3 ,并爬取歌词

作者: mbinary | 来源:发表于2018-06-16 12:56 被阅读8次

    最近想获取几首好听的网易云音乐文件,但是不是会员,只有缓存文件,而且经过加工了的。
    以前获取过某k歌的缓存文件,直接修改后缀名就行了,但是网易云音乐不行,sigh

    下面开始探索网易云音乐之旅:D

    1. 解密缓存文件

    在手机上的缓存文件在 netease/cloudmusic/Cache/里的Music1里, 歌词在Lyric里,(电脑上的路径可以在设置里找到)
    观察可以发现,歌曲缓存文件包括两个,一个是index文件.idx!,另一个是歌曲文件,index文件和歌词文件(歌曲id命名)都是txt文件,可以直接打开,而歌曲文件.uc!打开错误。缓存文件是修改过的。如图:

    file

    进一步地,缓存文件和源文件大小一样大,所以没有经过压缩,最简单的想法是异或运算,这样最简单,加密,解密一样的操作。逐个尝试,发现每字节和0xa3异或即可,得到正确的文件,可以播放,哈哈 :smiley: 下面是代码,注意用bytearray修改bytes

    with open (fileName,'rb') as f:
        btay = bytearray(f.read())
    with open(newFile,'wb') as out:
        for i,j in enumerate(btay):
            btay[i] = j ^ 0xa3
        out.write(bytes(btay))
    

    2. 获得歌曲信息

    为了给歌曲文件正确命名,我想获得歌曲题目和歌手信息。虽然.idx!索引文件包含一些属性,但是没有歌曲标题和歌手,不过重要的是musicId,这是歌曲的唯一标识。然后发现.idx! .uc!文件都是以id开头的,且歌词文件是id命名的。

    打开网易云音乐的网页,发现网址是
    https://music.163.com/#/song?id=186240
    所以后面更改id就能从这网页爬取标题,歌手,歌词哦。

    不过不到万不得已还是不用爬虫(后面会用到),了解到mp3等文件格式有一些metadata,mp3文件的id3 tag里面就包含标题,歌手。这是wiki的介绍

    mp3

    然后找python模块,网上说eyeD3比较好用,但是我安装好后提示libmagic找不到,搜索问题未能解决(如果你有解决办法,请告诉我,十分感谢), 然后用的mutagen模块,这个模块能操作很多格式的文件,这是效果

    id3

    3. 获取歌词(大boss :scream: )

    这一步有点难了。网易云音乐的歌词改版了很多,新旧版本都存在,而且有些还没有歌词。本来想用json,但是遇到一些编码以及解析问题,所以我用rb打开歌词文件

    3.1. lyric文件

    这是歌词文件内容

    file

    从这个文件中读取,但文件中没有歌词内容,我就从网页中爬取。 解析这个文件,由于没有统一的键,所以我用正则表达式r'(lyric|lrc|klyric|kalaokLyric|tlyric)\s*[\'\"]:\s*[\'\"]\s*\[')来检查是否有歌词内容

    # self.hasLrcPt= re.compile(r'(lyric|lrc|klyric|kalaokLyric|tlyric)\s*[\'\"]:\s*[\'\"]\s*\[')
    # self.lrcKey = 'lyric|lrc|klyric|kalaokLyric|tlyric'.split('|')
    
    def noLrc(self,s):
            '''judge if a dict or a string  has lyrics'''
            if isinstance(s,str):
                return self.hasLrcPt.search(s) is  None
            else:
                return not  reduce(or_,[i in s and s[i]!='' for i in self.lrcKey]) 
    

    检查到有歌词后,可以发现每句是这样的

    [0:09.000]平安夜,亵渎的夜晚\n

    最开始用的r'\[\d+,\d+\](\(\d+,\d+\)(\w))+\n'),然而总是匹配不到,在交互模式又匹配得很精确,在这里浪费了很多时间,最后发现是\n的问题,在正则表达式中要用\\n,作为字符串在交互模式下打印出来只显示了\n, :weary: , 心累 ,改为r'\[\d+:\d+\.\d+\](.*?)\\n'.

    3.2. 爬取歌词

    如果文件中没有,尝试用爬虫。爬取上面那个网址
    https://music.163.com/#/song?id=186240

    同样不能爬取到标题和歌词,发现是js代码的原因,不是同一个页面,后面找到这个api

    https://music.163.com/api/song/lyric?id=186240&lv=1&kv=1&tv=-1

    这个直接爬取过来json解析,然后正则匹配即可,但是对于
    lyric文件以及这个页面也没有的歌词,说明真的没有歌词了,得等热心网友提供给网易音乐了(

    注意由于是缓存文件,一些小音频可能id3 tag以及网页都没有信息,对于这些,我直接用的id命名

    4. 晒成果

    lrc
    music

    完整代码见github这里

    5. 感想 :flushed: (羞涩

    有时看书有点没有耐心,想实践,然而如果没有掌握好知识,实践的话就会踩很多坑,甚至可能还爬不起来有些坑。 还差得远呢,还得加油哦!

    6. and ... finally

    warning

    (学习使用异或加密 :see_no_evil:

    相关文章

      网友评论

        本文标题:从网易云音乐缓存文件得到 MP3 ,并爬取歌词

        本文链接:https://www.haomeiwen.com/subject/fucbeftx.html