Python 爬虫--下载音乐

       这是一个Python爬虫的程序,是利用各大音乐商开放的api,获取参数的。当然了收费的音乐肯定是不能下的。项目是早期写的,参阅不少其他的博客,但现在已经记不得了,如果大家发现有出处,请告知,我补全参考博文部分。

 1、从网易下载歌曲

 2、从qq下载音乐

3、从酷狗下载音乐

4、从酷我下载音乐

5、查看下载的歌曲,歌曲文件在和程序同级目录的song目录中。

6、附上代码,如果看不懂,最好打印出来,分解一下。 

"""
版本:python 3.6
作者:物联网菜鸟
介绍:这是一个爬取网易云音乐、QQ音乐、酷狗音乐的小程序,实现搜索并下载的功能
当然bug无处不在,希望大家可以完善!
初版时间:2019年8月11
"""
import requests
import os
import json
import urllib
from fake_useragent import UserAgent
import re
import time
  
########################################
"""
wy_downSong(song_id,song_name)
这个函数是为了下载网易音乐
参数是歌曲的id和歌曲的名称,均为字符串类型
无返回值
"""
def wy_dongLyric(song_id,song_name):
    url='http://music.163.com/api/song/lyric?id=' + song_id + '&lv=1&kv=1&tv=-1'
    print(url)
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'
    }
    if os.path.exists("song"):
       pass
    else:
        os.mkdir("song")
        print("创建音乐文件夹成功!")
    if os.path.exists("./song/"+song_name+".lrc"):
        os.remove("./song/"+song_name+".lrc")
        #判断要下载的歌词是否存在,删除已有歌词,目的是重新下载
    try:
        with open("./song/"+song_name+'.lrc',"wb") as f:
            f.write(requests.get(url,headers=headers).content)
        print("下载歌词成功!")
    except Exception as e:
        print("下载歌词失败!",e)
        
def wy_downSong(song_id,song_name):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'
    }
    url = 'http://music.163.com/song/media/outer/url?id='+song_id+'.mp3'
    if os.path.exists("song"):
       pass
    else:
        os.mkdir("song")
        print("创建音乐文件夹成功!")
    if os.path.exists("./song/"+song_name+".mp3"):
        os.remove("./song/"+song_name+".mp3")
        #判断要下载的音乐是否存在,删除已有音乐,目的是重新下载
    try:
        with open("./song/"+song_name+'.mp3',"wb") as f:
            f.write(requests.get(url,headers=headers).content)
        print("下载音乐成功!")
    except Exception as e:
        print("下载音乐失败!",e)
    
"""
wy_getSongList(serch_text)
这个函数是为了得到音乐列表,是经过修饰的列表,将原始音乐列表简化
参数是搜索的歌曲名称,字符串类型
返回新的歌曲列表,列表类型
"""
def wy_getSongList(serch_text):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
        'Referer': 'https://music.163.com/',
        'Host': 'music.163.com'
    }
    url="http://music.163.com/api/search/get/"
    data = {
        's': serch_text,
        'type': 1,
        'offset': 0,
        'total': "true",
        'limit': 10
    }
    try:
        r=requests.post(url,headers=headers,data=data)
        print("网易云音乐列表链接正确!")
        json_result= r.json()
    except Exception as e:
        print("获取网易音乐列表时网络错误!",e)
        return
    song_list=json_result.get("result").get("songs")
    new_song_list=[]
    for i in song_list:
        new_song_dir={}
        new_song_dir["id"]=i.get("id")
        new_song_dir["name"]=i.get("name")
        new_song_dir["artists"]=""
        new_song_dir["fee"]=i.get("fee")
        for j in i.get("artists"):
            new_song_dir["artists"]+="/"+j.get("name")
            #拼接歌手
        new_song_dir["album"]=i.get("album").get("name")
        new_song_list.append(new_song_dir)
    return new_song_list

"""
wyMusic(serch_text)
这个函数是网易音乐主函数
参数为搜索的内容,字符串类型
无返回值
"""
def wyMusic(serch_text):
    print("当前选择网易路线下载!")
    new_song_list=wy_getSongList(serch_text)
    index=0
    print("编号\t歌名\t歌手\t专辑\t是否是vip 1是,8不是")
    for i in new_song_list:
        print(index,"\t",i.get("name"),"\t",i.get("artists"),"\t",i.get("album"),"\t",i.get("fee"))
        index+=1
    index=input("选择下载的编号:")
    select_song_dir=new_song_list[int(index)]
    wy_downSong(str(select_song_dir.get("id")),select_song_dir.get("name"))
    wy_dongLyric(str(select_song_dir.get("id")),select_song_dir.get("name"))

########################################
"""
qq_getSongList(search_text)
这个函数是qq音乐搜索函数
参数为搜索的内容,字符串类型
返回音乐列表
"""        
def qq_getSongList(search_text):
    #这个是得到qq音乐的列表
    headers = {
        'user-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'
    }
    search_text = urllib.parse.quote(search_text)
    url = 'https://c.y.qq.com/soso/fcgi-bin/client_search_cp?aggr=1&cr=1&p=1&n=20&w=%s' % search_text
    try:
        response = requests.get(url, headers=headers).text.encode('gbk', 'ignore').decode('gbk').split('callback')[-1].strip('()')
        response = json.loads(response)
        return response['data']['song']
    except Exception as e:
        print("获取搜索列表失败!",e)
        return {'totalnum':0 }

"""
print_info(songs)
函数是打印音乐列表
参数是歌曲列表
无返回值
"""
def print_info(songs):
    #打印音乐列表
    print('编号\t歌曲名字\t作者\t专辑')
    for num, song in enumerate(songs):
        songname = song['songname']
        singer_length = len(song['singer'])
        singers = []
        for i in range(singer_length):
            singers.append(song['singer'][i]['name'])
        singers = ('/').join(singers)
        album_name = song['albumname']
        print(num,"\t",songname,'\t' ,singers, '\:',album_name)

"""
get_mp3_url(songs,num)
函数是得到指定歌曲的url
参数是歌曲列表和选择的序号(整形)
返回歌曲url
"""
def get_mp3_url(songs,num):
    #得到音乐的地址
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'
    }
    media_mid = songs['list'][num]['media_mid']
    url_1 = 'https://c.y.qq.com/base/fcgi-bin/fcg_music_express_mobile3.fcg?g_tk=5381&cid=205361747&songmid=%s&filename=C400%s.m4a&guid=6800588318' % (media_mid,media_mid)
    response = requests.get(url_1,headers=headers).json()
    vkey= response['data']['items'][0]['vkey']
    if vkey:
        url_2 = 'https://dl.stream.qqmusic.qq.com/C400%s.m4a?vkey=%s&guid=6800588318&uin=0&fromtag=66' % (media_mid,vkey)
        print(url_2)
        return url_2
    return None

"""
qq_downSong(url,filename)
下载函数
参数是歌曲url,和歌曲的名字
无返回值

"""
def qq_downSong(url,filename):
    #下载音乐
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'
    }
    if os.path.exists("song"): 
       pass
    else:
        os.mkdir("song")
        print("创建文件夹成功!")
    if os.path.exists("./song/"+filename+".m4a"):
        os.remove("./song/"+filename+".m4a")
    try:
        with open("./song/"+filename+'.m4a',"wb") as f:
            f.write(requests.get(url,headers=headers).content)
        print("下载音乐成功!")
    except Exception as e:
        print("下载音乐失败!",e)

"""
qqMusic(search_text)
qq音乐主函数
参数搜索内容,字符串类型
无返回值
"""
def qqMusic(search_text):
    #qq音乐主函数
    songs = qq_getSongList(search_text)
    if songs['totalnum'] == 0 :
        print('没有搜到此歌曲,请换个关键字')
    else: 
        print_info(songs['list'])
        num = input('请选择下载的歌曲,输入序号:')
        url = get_mp3_url(songs,int(num))
        if not url :
            print('歌曲已下架 找不到下载地址 下载失败')
        else:
            songname = songs['list'][int(num)]['songname']
            qq_downSong(url, songname)
            
###########################################
"""
kg_getSongList(search_text)
返回音乐列表
"""
def kg_getSongList(search_text):
    # UserAgent是识别浏览器的一串字符串,相当于浏览器的身份证,
    # 在利用爬虫爬取网站数据时,频繁更换UserAgent可以避免触发相应的反爬机制。
    ua = UserAgent(use_cache_server=False)
    search_url = "https://songsearch.kugou.com/song_search_v2?callback=jQuery112405132987859127838_1550204317910&page" \
                 "=1&pagesize=30&userid=-1&clientver=&platform=WebFilter&tag=em&filter=2&iscorrection=1&privilege_fil" \
                 "ter=0&_=1550204317912&keyword={}".format(search_text)
    headers = {
        "User-Agent": ua.random
    }
    try:
        res = requests.get(search_url, headers=headers)
        start = re.search("jQuery\d+_\d+\(?", res.text)
        js = json.loads(res.text.strip().lstrip(start.group()).rstrip(")"))
        # 注意:末尾有一个换行需要去掉
        return js['data']['lists']
    except Exception as e:
        print("获取搜索列表失败!",e)
        
"""
kg_downSong(url,song_name)
下载音乐
"""
def kg_downSong(url,song_name):
    if os.path.exists("song"):
       pass
    else:
        os.mkdir("song")
        print("创建文件夹成功!")
    if os.path.exists("./song/"+song_name+".mp3"):
        os.remove("./song/"+song_name+".mp3")
    try:
        with open("./song/"+song_name + ".mp3", "wb")as f:
            f.write(requests.get(url).content)
        print("歌曲已下载完成!")
    except Exception as e:
        print("歌曲下载失败!",e)

"""
kgMusic(search_text)
酷狗音乐主函数

"""
def kgMusic(search_text):
    ua = UserAgent()
    headers = {
        "Cookie": "kg_mid=3786e26250f01bf2c64bc515820d9752; Hm_lvt_aedee6983d4cfc62f509129360d6bb3d=1559960644; Hm_lpvt_aedee6983d4cfc62f509129360d6bb3d=1559960644; ACK_SERVER_10015=%7B%22list%22%3A%5B%5B%22bjlogin-user.kugou.com%22%5D%5D%7D; ACK_SERVER_10016=%7B%22list%22%3A%5B%5B%22bjreg-user.kugou.com%22%5D%5D%7D; ACK_SERVER_10017=%7B%22list%22%3A%5B%5B%22bjverifycode.service.kugou.com%22%5D%5D%7D; kg_dfid=0iEqIA1uep0h0AogH30Jq1Od; kg_dfid_collect=d41d8cd98f00b204e9800998ecf8427e",
        "Host": "www.kugou.com",
        "Referer": "http://www.kugou.com/",
        "UserAgent": ua.random
    }
    song_list = kg_getSongList(search_text)
    num_totl=len(song_list) if len(song_list)<10 else 10
    for i in range(num_totl):
        print(str(i + 1) + ">>>" + str(song_list[i]['FileName']).replace('<em>', '').replace('</em>', ''))
    num = int(input("\n请输入您想要下载的歌曲序号:"))
    print("请稍等,下载歌曲中...")
    time.sleep(1)
    file_hash = song_list[num - 1]['FileHash']
    hash_url = "http://www.kugou.com/yy/index.php?r=play/getdata&hash={}".format(file_hash)
    print(hash_url)
    try:
        hash_res = requests.get(hash_url, headers=headers)
        hash_js = hash_res.json()  # json格式
        song_name=hash_js["data"]["audio_name"]
        play_url = hash_js['data']['play_url']
        kg_downSong(play_url,song_name)
    except Exception as e:
        print("下载歌曲失败!",e)

###########################################

def kw_getSongList(search_text):
    headers={
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36"
    }
    url="http://search.kuwo.cn/r.s?SONGNAME=%s&ft=music&rformat=json&encoding=utf8&rn=8&callback=song&vipver=MUSIC_8.0.3.1"%search_text
    try:
        r=requests.get(url,headers=headers)
        song_list_str=re.findall("try{var jsondata=(.*)",r.text)
        song_json_str=re.sub("'",'"',song_list_str[0])
        song_list=json.loads(song_json_str)["abslist"]
        return song_list 
    except Exception as e:
        print("获取列表失败",e)

def kw_getSongUrl(song_list):
    index=0
    headers={
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36"
    }
    for i in song_list:
        print(index,"\t",i["SONGNAME"],"\t",i["ARTIST"],"\t",i["SUBTITLE"])
        index+=1

    index=int(input("输入要下载的id:"))
    url="http://antiserver.kuwo.cn/anti.s?%20response=url&rid="+song_list[index]["MUSICRID"]+"%22&format=mp3&type=convert_url"
    try:
        song_url=requests.get(url,headers=headers).text
        song_name=song_list[index]["SONGNAME"]
        return song_url,song_name
    except Exception as e:
        print("获取歌曲连接失败!",e)
           
def kw_downSong(song_url,song_name):
    headers={
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36"
    }
    if os.path.exists("song"):
       pass
    else:
        os.mkdir("song")
        print("创建文件夹成功!")
    if os.path.exists("./song/"+song_name+".mp3"):
        os.remove("./song/"+song_name+".mp3")
    try:
        with open("./song/"+song_name + ".mp3", "wb")as f:
            f.write(requests.get(song_url).content)
        print("歌曲已下载完成!")
    except Exception as e:
        print("歌曲下载失败!",e)

        
def kwMusic(search_text):
    song_list=kw_getSongList(search_text)
    song_url,song_name=kw_getSongUrl(song_list)
    kw_downSong(song_url,song_name)
    
###########################################
def main():
    while True:
        search_text=input("输入要搜索的歌曲名称:")
        flag=input("选择音乐网站:\n0,退出\n1,网易\n2,QQ\n3,酷狗\n4,酷我\n:")
        if flag=="1":
            wyMusic(search_text)
        if flag== "2":
            qqMusic(search_text)
        if flag=="0":
            break
        if flag=="3":
            kgMusic(search_text)
        if flag=="4":
            kwMusic(search_text)
    
if __name__=="__main__":
    main()

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江湖人称王某人的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值