Pyhton酷我音乐爬取,爬虫MP3文件下载核心代码

news/2024/7/19 10:39:15 标签: 爬虫, python, 开发语言

Pyhton酷我音乐爬取MP3文件案例

一、数据爬取思路分析

找到数据来源,通过浏览器抓包工具

通过网络标签和关键字搜索

查看网页源代码,找到数据位置

确定实现思路和技术实现方式

二、代码实现

发送请求

获取数据

解析数据

保存数据

使用会员登录可下载所有列表歌曲,非会员只能下载免费的MP3歌曲
支持分页下载,下载所有分页列表歌曲

关注微信公众号【站在前沿】,回复kuwo,获取完整代码下载地址

kuwo.py

def downMp3s(musicIds, musicNames):
    for musicId, musicName in zip(musicIds, musicNames):
        url = f'http://www.kuwo.cn/api/v1/www/music/playUrl?mid={musicId}&type=music&httpsStatus=1&reqId=7e2a25c3-51e3-11ee-b0bd-49dd3fc18b18&plat=web_www&from='
        # logging.debug(until.getResJson(url=url, headers=headers))
        code = until.getResJson(url=url, headers=headers)['code']
        if code == 200:
            downUrl = until.getResJson(url=url, headers=headers)['data']['url']
            # logging.debug(downUrl)
            until.downBinFile(downUrl, '', 'mp3', musicName + '.mp3')
            logging.info('歌曲:' + musicName + '.mp3 下载完成')
        elif code == -1:
            logging.info('歌曲:' + musicName + '为付费内容,无法下载')
        else:
            logging.info('歌曲:' + musicName + '下载时返回Code为' + code)


if __name__ == '__main__':
    urlMp3List = 'http://www.kuwo.cn/api/www/bang/bang/musicList'
    params = {
        "bangId": "93",
        "pn": "1",
        "rn": "20",
        "httpsStatus": "1",
        "reqId": "787a5650-51e8-11ee-adef-53b278c91f8b",
        "plat": "web_www",
        "from": ""
    }
    for pn in range(1, 16):
        params['pn'] = str(pn)
        mp3List = until.getResJson3(urlMp3List, headers, params)
        # pprint.pprint(mp3List)
        musicIds = []
        musicNames = []
        for i in range(0, 20):
            musicIds.append(mp3List['data']['musicList'][i]['rid'])
            musicNames.append(mp3List['data']['musicList'][i]['name'])
        # logging.debug(musicIds)
        # logging.debug(musicNames)
        # 开始下载当前页的歌曲列表
        downMp3s(musicIds, musicNames)
        logging.info('===============第' + str(pn) + '页下载完成=================')

 until.py

import logging
import requests
import re
import datetime
from tqdm import tqdm

# 配置日志输出的格式和级别
logging.basicConfig(
    level=logging.INFO,  # 设置日志级别为DEBUG
    format="%(asctime)s - %(levelname)s - %(message)s"  # 指定日志输出的格式,包含时间、级别和消息
)


# -----------------网页内容请求-------------------
# ------------get方式
def getResText(url, headers):
    with requests.get(url=url, headers=headers) as res:
        res.encoding = "utf-8"
        resText = res.text
    return resText


def getResJson(url, headers):
    with requests.get(url=url, headers=headers) as res:
        res.encoding = "utf-8"
        json = res.json()
    return json


def getResJson3(url, headers, params):
    with requests.get(url=url, headers=headers, params=params) as res:
        res.encoding = "utf-8"
        json = res.json()
    return json


# ------------post方式
def postResText(url, headers, data):
    with requests.post(url=url, headers=headers, data=data) as res:
        res.encoding = "utf-8"
        resText = res.text
    return resText


def postResJson(url, headers, data):
    with requests.post(url=url, headers=headers, data=data) as res:
        res.encoding = "utf-8"
        json = res.json()
    return json


# -----------------下载文件-------------------
# -----------------------------------------------------get方式
# 下载视频、图片、文件等
def downBinFile(url, headers, path, fileName):
    startTime = datetime.datetime.now()
    if headers == '':
        with requests.get(url=url, stream=True) as res:
            content = res.content
    else:
        with requests.get(url=url, headers=headers, stream=True) as res:
            content = res.content
    saveBinFile(content, path, fileName)
    logging.info(
        '文件[' + fileName + ']下载完成,总共耗时{}毫秒'.format((datetime.datetime.now() - startTime).total_seconds() * 1000))


# 下载文件显示进度条
def downBinFileShowBar(url, headers, path, fileName):
    startTime = datetime.datetime.now()
    if headers == '':
        with requests.get(url=url, stream=True) as file:
            saveBinFileShowBar(file, path, fileName)
    else:
        with requests.get(url=url, headers=headers, stream=True) as file:
            saveBinFileShowBar(file, path, fileName)
    logging.info(
        '文件[' + fileName + ']下载完成,总共耗时{}毫秒'.format((datetime.datetime.now() - startTime).total_seconds() * 1000))


# ----------------------------------------------------post方式
# 下载视频、图片、文件等
def postDownBinFile(url, headers, path, fileName):
    startTime = datetime.datetime.now()
    if headers == '':
        with requests.post(url=url, stream=True) as res:
            content = res.content
    else:
        with requests.post(url=url, headers=headers, stream=True) as res:
            content = res.content
    saveBinFile(content, path, fileName)
    logging.info(
        '文件[' + fileName + ']下载完成,总共耗时{}毫秒'.format((datetime.datetime.now() - startTime).total_seconds() * 1000))


# 下载文件显示进度条
def postDownBinFileShowBar(url, headers, path, fileName):
    startTime = datetime.datetime.now()
    if headers == '':
        with  requests.post(url=url, stream=True) as file:
            saveBinFileShowBar(file, path, fileName)
    else:
        with requests.post(url=url, headers=headers, stream=True) as file:
            saveBinFileShowBar(file, path, fileName)
    logging.info(
        '文件[' + fileName + ']下载完成,总共耗时{}毫秒'.format((datetime.datetime.now() - startTime).total_seconds() * 1000))


# -----------------------------------------------------保存文件
# 通过数据流保存视频、图片、文件等
def saveBinFile(content, path, fileName):
    file = re.sub(r"[<>:\"/\\|?*]+", "", fileName)
    file = file.replace(' ', '')
    with open(path + '\\' + file, 'wb') as f:
        f.write(content)


# 通过请求对象保存视频、图片、文件等,同时显示进度条
def saveBinFileShowBar(file, path, fileName):
    fileSize = int(file.headers.get('Content-Length'))
    progressBar = tqdm(total=fileSize)
    fileName = re.sub(r"[<>:\"/\\|?*]+", "", fileName)
    fileName = fileName.replace(' ', '')
    with open(path + '\\' + fileName, 'wb') as f:
        for chunk in file.iter_content(1024 * 1024 * 2):
            f.write(chunk)
            progressBar.set_description(f'正在下载[' + fileName + ']中...')
            progressBar.update(1024 * 1024 * 2)
    progressBar.set_description('文件[' + fileName + ']下载完成')
    progressBar.close()

def checkFileName(fileName):
    return re.sub(r"[<>:\"/\\|?*]+", "", fileName).replace(' ', '')

关注微信公众号【站在前沿】,回复kuwo,获取完整代码下载地址 


http://www.niftyadmin.cn/n/5144126.html

相关文章

云尘-Node1 js代码

继续做题 拿到就是基本扫一下 nmap -sP 172.25.0.0/24 nmap -sV -sS -p- -v 172.25.0.13 然后顺便fscan扫一下咯 nmap: fscan: 还以为直接getshell了 老演员了 其实只是302跳转 所以我们无视 只有一个站 直接看就行了 扫出来了两个目录 但是没办法 都是要跳转 说明还是需要…

梯度消失和梯度爆炸的原因

梯度消失和梯度爆炸 梯度爆炸和梯度消失本质上是因为梯度反向传播中的连乘效应。 梯度下降算法 举一个简单的例子,函数表达式为loss 2w^2 4w,如下图 ​​​​​​​ ​​​​​​​ ​​​​​​​ 为了求得w的最优值,使得loss最小,从上图很容易看…

曾经遇到过的无法解释的问题

因为不能直接展示生产数据与生产数据结构&#xff0c;所以写一个简单的例子 class Stu{ private String name; private int age; getter setter constructor 略 } List<Stu> list new ArrayList(); list.add(new Stu("s1",16)); list.add(new Stu("…

LiveNVR监控流媒体平台局域网Onvif/RTSP/SDK等方式接入监控视频后转GB28181/GB35114级联输出,上级平台无法播放如何抓包分析

1、第一步&#xff1a;抓包工具准备 1.1、Linux 使用 tcpdump 进行抓包&#xff0c;如果系统无此命令&#xff0c;自行安装 1.2、windows 下载安装 wireshark 进行抓包 2、第二步&#xff1a;找到上级平台ip 在基础配置里面GB28181级联配置中SIP服务IP 3、第三步&#…

Unreal 断线重连、AI控制

浅析UE5 DS的断线重连机制 wizardcell.com ReloginProject 流程说明 当服务器判断某个玩家掉线的时候&#xff0c;会删除对应的PlayerController void APlayerController::Destroyed()if (Player NULL && GetLocalRole() ROLE_Authority)// 销毁PawnPawnLeavingGa…

垃圾分类箱通过工业4G路由器实现无人值守远程管理

据今年发布的相关数据统计&#xff0c;人们日常生活中每人每天至少能制造1.2kg垃圾&#xff0c;在环保事业中日常垃圾处理已经成为一项紧迫且不可忽视的任务。为了实现城市清洁和环境保护&#xff0c;越来越多的地区开始引入垃圾分类箱。传统的垃圾分类箱管理方式存在着一些不便…

15种稳定扩散模型的技术示例

推荐Stable Diffusion自动纹理工具&#xff1a; DreamTexture.js自动纹理化开发包 什么是稳定扩散模型&#xff1f; 潜在扩散模型 &#xff08;LDM&#xff09; 是一种图像生成技术&#xff0c;其工作原理是在潜在表示空间中迭代“去噪”数据&#xff0c;然后将表示解码为完整…

shell_62.shell脚本生成一个标准的 SQL INSERT 语句

无论是将文件读入脚本&#xff0c;还是将数据从脚本输出到文件&#xff0c;都会用到文件重定向&#xff0c;这是一种很 常见的操作。本节中的示例脚本两种功能皆有。它会读取 CSV 格式的数据文件&#xff0c;输出 SQL INSERT 语句&#xff0c;并将数据插入数据库。 shell 脚本使…