音乐-爬虫


import requests, os, time, loguru
import pandas as pd
from concurrent.futures import ThreadPoolExecutor


def get_mid(url):  # 得到歌曲的mid
    headers = {  # 传入必要请求头,反爬
        "Accept": "application/json, text/plain, */*",
        "Accept-Encoding": "gzip, deflate",
        "Accept-Language": "zh-CN,zh;q=0.9",
        "Connection": "keep-alive",
        "Cookie": "_ga=GA1.2.2058800930.1642474837; _gid=GA1.2.1174281146.1642474837; Hm_lvt_cdb524f42f0ce19b169a8071123a4797=1642490265,1642490289,1642490402,1642498818; Hm_lpvt_cdb524f42f0ce19b169a8071123a4797=1642499234; kw_token=YK4UZW2UPL",
        "csrf": "YK4UZW2UPL",
        "Host": "www.kuwo.cn",
        "Referer": "http://www.kuwo.cn/",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36",
    }
    resp = requests.get(url=url, headers=headers).json()
    content = resp["data"]["list"]
    content_lis = []
    for i in content:
        mid = i["musicrid"].split("_")[-1]
        atr = i["artist"]
        names = i["name"]
        content_lis.append({"编号": mid, "歌名": names, "歌手": atr})
    return content_lis


def download(url_dic):  # 下载音乐
    headers1 = {  # 得到音乐下载地址的请求头
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
        "Accept-Encoding": "gzip, deflate",
        "Accept-Language": "zh-CN,zh;q=0.9",
        "Cache-Control": "max-age=0",
        "Connection": "keep-alive",
        "Cookie": "_ga=GA1.2.2058800930.1642474837; _gid=GA1.2.1174281146.1642474837; Hm_lvt_cdb524f42f0ce19b169a8071123a4797=1642509517,1642511738,1642514710,1642551220; Hm_lpvt_cdb524f42f0ce19b169a8071123a4797=1642551237; kw_token=GR2I2YW69IE",
        "Host": "www.kuwo.cn",
        "Upgrade-Insecure-Requests": "1",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36",
    }
    resp = requests.get(url=url_dic["url"], headers=headers1).json()
    dl = resp["data"]["url"]  # 得到的歌曲url
    time.sleep(1)
    print(dl, "\n如果没有这首歌,则可以通过这个链接下载")
    time.sleep(1)
    resp = requests.get(url=dl)
    if resp.status_code == 200:  # 判断访问是否成功,如果失败则直接退出,避免报错
        rp = resp.content
        try:  # 判断有没有D盘和E盘
            if not os.path.exists('E:/Python/1付费音乐下载/音乐文件'):
                os.mkdir("E:/Python/1付费音乐下载/音乐文件")
            with open(f"E:/Python/1付费音乐下载/音乐文件/{url_dic['name']}.mp3", "wb") as f:
                f.write(rp)
            loguru.logger.info(f"{url_dic['name']}下载完成")
            print("歌曲下载完成!")
        except:
            if not os.path.exists('E:/Python/1付费音乐下载/音乐文件'):
                os.mkdir("E:/Python/1付费音乐下载/音乐文件")
            with open(f"E:/Python/1付费音乐下载/音乐文件/{url_dic['name']}.mp3", "wb") as f:
                f.write(rp)
            loguru.logger.info(f"{url_dic['name']}下载完成")
            print("歌曲下载完成!")
    else:
        print("很遗憾!!!访问失败")


def show_menu_song(df, data):  # 得到选择要下载的歌曲,UI展示,选择要下载的歌曲
    print("******** 这里找到了30首歌,请选择下载一首或多首 ********")
    while True:
        choice = input("******* 请输入编号(如果有多个编号请用空格分开)*********\n").split()
        temp = [i for i in choice if i in list(df.index)]
        if temp:
            choice1 = []
            for i in data:
                if i["编号"] in choice:
                    choice1.append({"name": f"{i['歌手']}", "mid": f"{i['编号']}"})  # 返回字典,便于索引
            print("正在准备下载,请稍等!")
            return choice1
        else:
            for i in choice:
                if i not in choice:
                    print(f"没有编号:{i}")
            print("请重新输入!")


def main1():  # 按照歌名下载
    name = input("************* 请输入您想要下载的歌曲*****************\n")
    url = f"http://www.kuwo.cn/api/www/search/searchMusicBykeyWord?key={name}&pn=1&rn=30&httpsStatus=1"
    data = get_mid(url)  # 通过调用函数的到mid
    df = pd.DataFrame(data).set_index("编号")
    print(df)
    choice = show_menu_song(df, data)  # 存储的是歌曲的编号
    url_api = [f"http://www.kuwo.cn/api/v1/www/music/playUrl?mid={i['mid']}&type=convert_url&httpsStatus=1" for i in
               choice]  # 使用列表生成式快速生成url_api
    url_name = [f"{name}_{choice[i]['name']}" for i in range(len(url_api))]
    url_list = []  # 存储名字和url
    for i in range(len(url_api)):
        url_list.append({"name": url_name[i], "url": url_api[i]})  # 以键值对的方式存储,便于命名

    return url_list  # 返回结果


def main2():  # 按照歌手名字下载
    print("*************************************************")
    name = input("************** 请输入歌手名字 *****************\n")
    while True:
        page = input("******* 请输入要下载的页数,一页30首歌 ***********\n")
        if 0 < eval(page) < 10 and isinstance(eval(page), int):  # 一般9页,210首歌应该足够,防止输入页数过多,造成程序奔溃
            break
        else:
            print("请输入1到10的数字")  # 防止随便输入,提高程序的可用性
    print("*************************************************")
    url = f"http://www.kuwo.cn/api/www/search/searchMusicBykeyWord?key={name}&pn={page}&rn=30&httpsStatus=1"
    data = get_mid(url)  # 得到mid
    url_list = []  # 存放url
    for i in data:
        url_list.append({"name": i["歌名"],
                         "url": f'http://www.kuwo.cn/api/v1/www/music/playUrl?mid={i["编号"]}&type=convert_url&httpsStatus=1'})

    return url_list


def main():
    while True:  # 界面展示,供自己选择
        choice = input("*****根据歌手名字下载音乐还是歌名?1(歌名)/2(歌手)*******\n")
        print("*************************************************")
        if choice == "1":
            return main1()
        elif choice == "2":
            return main2()
        else:
            print("请按要求输入!")


if __name__ == '__main__':
    with ThreadPoolExecutor(50) as pol:  # 使用线程池开启下载
        pol.map(download, main())

    time.sleep(5)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值