进入千千音乐主页面,选择周杰伦的音乐告白气球,发现竟然是2016年的音乐试听都木有,悲伤。那么有没有办法可以获取到mp3文件呢?答案是肯定的。音乐下载可运行程序可在文末获取。

说干就干,打开榜单,选择新歌一首可以试听的,第一首生僻字就可以听。

《python实现千千音乐mp3下载》

1.分析接口信息

打开开发者工具,这种音乐文件肯定是通过api提交的,在毛毛多的请求中发现可以获取音乐文件的请求,看图

《python实现千千音乐mp3下载》

查看请求详细信息

《python实现千千音乐mp3下载》

参数songid在当前url地址 http://music.taihe.com/song/611238837里面可以找到,简单,from应该是web或者app之类的,format定义返回数据形式不用改,method不用改,_参数timestamp 13位时间戳,callback是返回数据的json数据的前面的名字,其中下划线后面的1546915161467为13位的timestamp 时间戳,前面的17200943498528136486就不知道是啥意思了,我们先不改变不知道的内容,试试知道含义的内容看看能否获取到信息

python3代码

    import requests
    import time
    apiurl= "http://musicapi.taihe.com/v1/restserver/ting"
    callback = "jQuery17200943498528136486_"+str(round(time.time()*1000))
    hua = str(round(time.time()*1000))
    params = {"method"="baidu.ting.song.playAAC","format":"jsonp","songid":"611238837","from":"web","callback":callback,"_":hua}
    text = requests.get(apiurl,params=params).text
    text
《python实现千千音乐mp3下载》

发现可以获取到结果,那么接下来就是批量下载下来听了。

2.批量下载音乐到本地

由于上面的例子返回的是json格式的文本,那么只需要使用json解析json文本获取mp3文件使用requests下载就可以了。上代码

    import requests
    import time
    import re,json

    def get_song_list():
        text = requests.get("http://music.taihe.com").text
        songid = re.findall(r'href="/song/(\d+)"',text)
        return songid
    def get_mp3_address_and_download(songid): 
        apiurl= "http://musicapi.taihe.com/v1/restserver/ting" 
        callback = "jQuery17200943498528136486_"+str(round(time.time()*1000)) 
        hua = str(round(time.time()*1000)) 
        params = {"method":"baidu.ting.song.playAAC","format":"jsonp","songid":songid,"from":"web","callback":callback,"_":hua} 
        text =  json.loads(requests.get(apiurl,params=params).text.split(callback)[1][1:-2])
        song_address = text["bitrate"]["file_link"]
        mp3w = open(songid+".mp3",'wb')
        mp3w.write(requests.get(song_address).content)
        mp3w.close()
    def main():
        try:
            for songid in get_song_list():
                get_mp3_address_and_download(songid)
        except:
            print("network error")

这下就完全下载了千千音乐首页的mp3了

《python实现千千音乐mp3下载》

3.搜索并下载音乐到本地

    #!env python
    import requests
    import re,json,time,sys
    def helpmessage():
        msg = r'''
           /\          /\          /\          /\
        /\//\\/\    /\//\\/\    /\//\\/\    /\//\\/\
     /\//\\\///\\/\//\\\///\\/\//\\\///\\/\//\\\///\\/\
    //\\\//\/\\///\\\//\/\\///\\\//\/\\///\\\//\/\\///\\
    \\//\/  本程序由 春江暮客             \/\\//
     \/      发布在www.bobobk.com 上             \/
     /\     程序打开后会打开网站           /\
    //\\    大家不要急着关闭                //\\
    \\//    作者:春江暮客                   \\//
     \/     用途:音乐下载                    \/
     /\     用法看程序运行时界面           /\
    //\\    如有任何疑问请在                //\\
    \\//    博客页面留言或者发邮件到    \\//
     \/     [email protected]                        \/
     /\                                              /\
    //\\/\                                        /\//\\
    \\///\\/\//\\\///\\/\//\\\///\\/\//\\\///\\/\//\\\//
     \/\\///\\\//\/\\///\\\//\/\\///\\\//\/\\///\\\//\/
        \/\\//\/    \/\\//\/    \/\\//\/    \/\\//\/
           \/          \/          \/          \/
    '''
        print(msg)

    def get_mp3_address_and_download(songid,songname):
        apiurl= "http://musicapi.taihe.com/v1/restserver/ting"
        callback = "jQuery17200943498528136486_"+str(round(time.time()*1000))
        hua = str(round(time.time()*1000))
        params = {"method":"baidu.ting.song.playAAC","format":"jsonp","songid":songid,"from":"web","callback":callback,"_":hua}
        text =  json.loads(requests.get(apiurl,params=params).text.split(callback)[1][1:-2])
        song_address = text["bitrate"]["file_link"]
        mp3w = open(songname+".mp3",'wb')
        mp3w.write(requests.get(song_address).content)
        mp3w.close()
    def search_music(keyword):
        if keyword in ["exit",u"退出"]:
            print(u"你选择了退出当前程序")

            sys.exit(0)

        text = requests.get("http://music.taihe.com/search?key=%s" % keyword).content.decode("utf8")
        songlist = re.findall(r'href="/song/(\d+)".*?data-songdata.*?title="(.+?)"',text)
        return songlist

    def main():
        song = input(u"请输入想要下载的音乐名称: ").strip()
        songlist = search_music(song)

        for i in range(len(songlist)):
            print("%d:  %s" % (i+1,songlist[i][1]))
        songid = input(u'请选择想要下载的歌曲前面的数字:')

        get_mp3_address_and_download(songlist[int(songid)-1][0],song)
        print(u"-------下载当前歌曲完成---------")
        print(u"退出请输入'exit'或者'退出'")
    if __name__=='__main__':
        helpmessage()
        while True:
    #        main()
            try:
                main()
            except:
                print(u"5秒后关闭程序")
                time.sleep(5)
                sys.exit(0)

然后使用pyinstaller打包脚本成exe文件,命令

    pyinstaller --onefile download_music.py 

总结

这里我们使用python的requests模块获取了千千音乐的首页音乐列表并下载到了本地,这种方式可以突破网页的限制实现vip音乐或者版权限制的mp3文件下载,为了方便大家调用下载,exe文件已经使用zip压缩。

音乐搜索下载可运行文件下载地址:

down_music.zip