python爬虫项目实战: 爬取酷狗音乐详细操作

您所在的位置:网站首页 关于酷狗音乐的说说句子简短 python爬虫项目实战: 爬取酷狗音乐详细操作

python爬虫项目实战: 爬取酷狗音乐详细操作

2024-07-12 10:54:28| 来源: 网络整理| 查看: 265

目标

主要目的为爬取酷狗音乐网站 mp3 任意音乐数据,并将爬取后的mp3数据保存为以.mp3后缀的音频文件

所用模块 hashlib => md5加密:提供了许多加密哈希算法,包括MD5、SHA-1、SHA-256等。 os     => 提供了访问操作系统功能的方法,例如文件操作、目录操作、进程管理等。 time    => 提供了处理时间的函数,包括获取当前时间、延时等功能。 requests=> 用于发送HTTP请求和处理响应。 re      => 提供了正则表达式操作的函数,用于在字符串中搜索、匹配和替换文本。 json    => 用于处理JSON数据,用于JSON格式转换。 tkinter => 提供了创建图形用户界面(GUI)的工具包,可以用于构建窗口、按钮、文本框等GUI元素。 基本思路 一 :音乐获取

打开浏览器,进入酷狗音乐网页,点击F12进入开发者模式

 点击上面一栏的媒体,可以看到mp3音乐文件

 可以发现这个文件就是当前音乐mp3媒体文件,但是我们需要找到它的来源处,可以在搜索出直接搜索横线那部分

 对比一下我们可以发现,我们所需要的mp3文件来源于此处。且位于play_url参数中,因此我们现在需要的就是爬取当前此文件。

 所以,我们先确定它的url。通过对比url与字符串参数发现,网页url只为“https://wwwapi.kugou.com/play/songinfo?”,其余都只是参数。

我们再取对比其他音乐的当前地址,发现他们只有“clienttime”,"encode","signature"这几个参数有变化。因此,我们可以知道,在爬取其他音乐时我们也只是需要改这几个参数便可以。

其中,发现“clienttime”为时间戳,"encode"为音乐ID,"signature"为md5加密的参数所以,我们只需要解密'signature'此参数,我们可以通过Ctrl+Swift+f打开全局搜索,搜索'signature',发现signature参数来与此js中,我们可以点击进入js查看

进入此处,我们在signature所需要的参数此行点击打上断电,并刷新页面。鼠标选中参数详细。会发现,此处就是我们所需要的参数。32位字母数字组合。再去查看它组合方式,就会发现它就是s的参数列表,转换成字符串直接用md5加密便可。而再通过对比一下s发现它的参数除了时间戳和音乐id完全一样,因此我们可以自己组合

而后组合加密得出signature参数,便可通过改变音乐id直接请求当前音乐的MP3信息。

二: 搜索指定获取

简单描述此操作 就是输入你想要的 音乐名 或 音乐名加作者名 搜索到音乐,获取 音乐ID 交给 第一步操作获得音乐mp3文件

我们现在需要模拟酷狗搜索栏操作,通过关键字搜索,并获取与关键字最相识的第一个音乐。

继续之前的操作,F12进入,并在左上角点击搜索按钮,搜索当前音乐名,点击进入。并进行对比发现song就是我们需要的数据

进入之后,我们会发现,搜索的所有的音乐内容都在lists中,我们只需要第一条的音乐内容, 并获取此音乐的ID与名字

再通过对比参数中signature发现和之前参数区别一样。因此,复制之前的操作便可

具体的步骤为同样搜索signature找到其js文件,打上断点调试,复制第一步的操作,得到signature参数,加入需要请求的url地址中“https://complexsearch.kugou.com/v2/search/song?”,便可得到搜索的音乐id  "EAlbumID"。将其给到第一步id中运行,便可以得到想要的音乐mp3数据。

三: 保存为mp3文件

获取到此音频地址后,对地址发送请求,将请求得到的数据以二进制的方式保存到指定目录文件夹中

代码部分 用到的模块 import hashlib import os import time import requests import re import json from tkinter import * 判断文件是否存在。不存在则创建改文件。         此文件为获取后保存的文件 def directory_create(): """判断文件是否存在。不存在则创建改文件""" directory = "./music_files" if not os.path.exists(directory): os.makedirs(directory) 通过搜索栏参数(音乐名)获取 搜索第一个的 音乐名 和 音乐id。  也就是第二个步骤(搜索指定获取)操作。 def audio_id_list(music_name): """ 通过搜索栏参数(音乐名)获取 搜索第一个的 音乐名 and ID :param music_name: 搜索栏参数(音乐名) 例如: 苏星婕 - 把回忆拼好给你 :return: 音乐名 音乐ID(苏星婕 - 把回忆拼好给你 72jrv7fa) """ timestamp = int(time.time() * 1000) headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36', } sign = MD5_sign_search(timestamp, music_name) datas = { 'callback': 'callback123', 'srcappid': '2919', 'clientver': '1000', 'clienttime': timestamp, 'mid': 'c4de83c1ebb2e73fc5ae95304a674918', 'uuid': 'c4de83c1ebb2e73fc5ae95304a674918', 'dfid': '3MmrUf3e5zpy3cStkN3Bn9oS', 'keyword': music_name, 'page': '1', 'pagesize': '30', 'bitrate': '0', 'isfuzzy': '0', 'inputtype': '0', 'platform': 'WebFilter', 'userid': '2078452878', 'iscorrection': '1', 'privilege_filter': '0', 'filter': '10', 'token': '483ef68936faa09268f3a42f7ab7ee31b584a3f155828a100c95fadf7c5ddd1e', 'appid': '1014', 'signature': sign, } response = requests.get(url='https://complexsearch.kugou.com/v2/search/song?', headers=headers, params=datas) callback_dict = re.findall('callback123\((.*)\)', response.text)[0] jsurl = json.loads(callback_dict) fileName = jsurl['data']['lists'][0]['FileName'] eMixSongID = jsurl['data']['lists'][0]['EMixSongID'] return fileName, eMixSongID 通过音乐ID爬取当前音乐的md3地址。也就是第一个操作部分(音乐获取) def fetch_url(audio_id): """ 通过音乐ID爬取当前音乐的md3地址 :param audio_id: 音乐ID(72jrv7fa) :return:音乐url(........mp3) """ timestamp = int(time.time() * 1000) print('audio_id:', audio_id) headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36', } sign = MD5_sign(timestamp, audio_id) datas = { 'srcappid': '2919', 'clientver': '20000', 'clienttime': timestamp, 'mid': 'c4de83c1ebb2e73fc5ae95304a674918', 'uuid': 'c4de83c1ebb2e73fc5ae95304a674918', 'dfid': '3MmrUf3e5zpy3cStkN3Bn9oS', 'appid': '1014', 'platid': '4', 'encode_album_audio_id': audio_id, 'token': '483ef68936faa09268f3a42f7ab7ee31b584a3f155828a100c95fadf7c5ddd1e', 'userid': '2078452878', 'signature': sign, } response = requests.get(url='https://wwwapi.kugou.com/play/songinfo?', headers=headers, params=datas) jsurl = response.json() # print('jsurl: ', jsurl) play_url = jsurl['data']['play_url'] return play_url 获取到此音频地址后,对地址发送请求,将请求得到的数据以二进制的方式保存到指定目录文件夹中。 def download_url(file_name, url_mp3): """ 通过已经获取的mp3文件保存到文件夹中 :param file_name: 音乐名 :param url_mp3: 音乐url(.....mp3) :return: 无 """ response = requests.get(url_mp3) try: with open(f"./music_files/{file_name}.mp3", "wb") as f: f.write(response.content) except: with open(f"./music_files/{int(time.time() * 1000)}.mp3", "wb") as f: f.write(response.content) print(f'{file_name}-----下载成功') 搜索页面和播放页面的两个signature的解密操作:MD5加密 def MD5_sign(timestamp, audio_id): """ 通过音乐id解密详情页单个音乐的signature参数 :param timestamp: 时间戳 :param audio_id: 音乐id(例如:72jrv7fa) :return: """ signature_list = ['NVPh5oo715z5DIWAeQlhMDsWXXQV4hwt', 'appid=1014', f'clienttime={timestamp}', 'clientver=20000', 'dfid=3MmrUf3e5zpy3cStkN3Bn9oS', f'encode_album_audio_id={audio_id}', 'mid=c4de83c1ebb2e73fc5ae95304a674918', 'platid=4', 'srcappid=2919', 'token=483ef68936faa09268f3a42f7ab7ee31b584a3f155828a100c95fadf7c5ddd1e', 'userid=2078452878', 'uuid=c4de83c1ebb2e73fc5ae95304a674918', 'NVPh5oo715z5DIWAeQlhMDsWXXQV4hwt'] string = "".join(signature_list) MD5 = hashlib.md5() MD5.update(string.encode('utf-8')) sign = MD5.hexdigest() # md5 32位加密内容 return sign def MD5_sign_search(timestamp, music_name): """ 通过音乐id解密搜索页的signature参数 :param timestamp:时间戳 :param music_name:搜索框音乐名(例如:把回忆拼好给你) :return:加密后32位md5参数(例如:72181cc6baf76ee0404837d5d657dd5c) """ signature_list = ['NVPh5oo715z5DIWAeQlhMDsWXXQV4hwt', 'appid=1014', 'bitrate=0', 'callback=callback123', f'clienttime={timestamp}', 'clientver=1000', 'dfid=3MmrUf3e5zpy3cStkN3Bn9oS', 'filter=10', 'inputtype=0', 'iscorrection=1', 'isfuzzy=0', f'keyword={music_name}', 'mid=c4de83c1ebb2e73fc5ae95304a674918', 'page=1', 'pagesize=30', 'platform=WebFilter', 'privilege_filter=0', 'srcappid=2919', 'token=483ef68936faa09268f3a42f7ab7ee31b584a3f155828a100c95fadf7c5ddd1e', 'userid=2078452878', 'uuid=c4de83c1ebb2e73fc5ae95304a674918', 'NVPh5oo715z5DIWAeQlhMDsWXXQV4hwt'] string = "".join(signature_list) MD5 = hashlib.md5() MD5.update(string.encode('utf-8')) sign_lis = MD5.hexdigest() # md5 32位加密内容 return sign_lis 总代码 总结 import hashlib import os import time import requests import re import json from tkinter import * def MD5_sign(timestamp, audio_id): """ 通过音乐id解密详情页单个音乐的signature参数 :param timestamp: 时间戳 :param audio_id: 音乐id(例如:72jrv7fa) :return: """ signature_list = ['NVPh5oo715z5DIWAeQlhMDsWXXQV4hwt', 'appid=1014', f'clienttime={timestamp}', 'clientver=20000', 'dfid=3MmrUf3e5zpy3cStkN3Bn9oS', f'encode_album_audio_id={audio_id}', 'mid=c4de83c1ebb2e73fc5ae95304a674918', 'platid=4', 'srcappid=2919', 'token=483ef68936faa09268f3a42f7ab7ee31b584a3f155828a100c95fadf7c5ddd1e', 'userid=2078452878', 'uuid=c4de83c1ebb2e73fc5ae95304a674918', 'NVPh5oo715z5DIWAeQlhMDsWXXQV4hwt'] string = "".join(signature_list) MD5 = hashlib.md5() MD5.update(string.encode('utf-8')) sign = MD5.hexdigest() # md5 32位加密内容 return sign def MD5_sign_search(timestamp, music_name): """ 通过音乐id解密搜索页的signature参数 :param timestamp:时间戳 :param music_name:搜索框音乐名(例如:把回忆拼好给你) :return:加密后32位md5参数(例如:72181cc6baf76ee0404837d5d657dd5c) """ signature_list = ['NVPh5oo715z5DIWAeQlhMDsWXXQV4hwt', 'appid=1014', 'bitrate=0', 'callback=callback123', f'clienttime={timestamp}', 'clientver=1000', 'dfid=3MmrUf3e5zpy3cStkN3Bn9oS', 'filter=10', 'inputtype=0', 'iscorrection=1', 'isfuzzy=0', f'keyword={music_name}', 'mid=c4de83c1ebb2e73fc5ae95304a674918', 'page=1', 'pagesize=30', 'platform=WebFilter', 'privilege_filter=0', 'srcappid=2919', 'token=483ef68936faa09268f3a42f7ab7ee31b584a3f155828a100c95fadf7c5ddd1e', 'userid=2078452878', 'uuid=c4de83c1ebb2e73fc5ae95304a674918', 'NVPh5oo715z5DIWAeQlhMDsWXXQV4hwt'] string = "".join(signature_list) MD5 = hashlib.md5() MD5.update(string.encode('utf-8')) sign_lis = MD5.hexdigest() # md5 32位加密内容 return sign_lis def fetch_url(audio_id): """ 通过音乐ID爬取当前音乐的md3地址 :param audio_id: 音乐ID(72jrv7fa) :return:音乐url(........mp3) """ timestamp = int(time.time() * 1000) print('audio_id:', audio_id) headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36', } sign = MD5_sign(timestamp, audio_id) datas = { 'srcappid': '2919', 'clientver': '20000', 'clienttime': timestamp, 'mid': 'c4de83c1ebb2e73fc5ae95304a674918', 'uuid': 'c4de83c1ebb2e73fc5ae95304a674918', 'dfid': '3MmrUf3e5zpy3cStkN3Bn9oS', 'appid': '1014', 'platid': '4', 'encode_album_audio_id': audio_id, 'token': '483ef68936faa09268f3a42f7ab7ee31b584a3f155828a100c95fadf7c5ddd1e', 'userid': '2078452878', 'signature': sign, } response = requests.get(url='https://wwwapi.kugou.com/play/songinfo?', headers=headers, params=datas) jsurl = response.json() # print('jsurl: ', jsurl) play_url = jsurl['data']['play_url'] return play_url def audio_id_list(music_name): """ 通过搜索栏参数(音乐名)获取 搜索第一个的 音乐名 and ID :param music_name: 搜索栏参数(音乐名) 例如: 苏星婕 - 把回忆拼好给你 :return: 音乐名 音乐ID(苏星婕 - 把回忆拼好给你 72jrv7fa) """ timestamp = int(time.time() * 1000) headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36', } sign = MD5_sign_search(timestamp, music_name) datas = { 'callback': 'callback123', 'srcappid': '2919', 'clientver': '1000', 'clienttime': timestamp, 'mid': 'c4de83c1ebb2e73fc5ae95304a674918', 'uuid': 'c4de83c1ebb2e73fc5ae95304a674918', 'dfid': '3MmrUf3e5zpy3cStkN3Bn9oS', 'keyword': music_name, 'page': '1', 'pagesize': '30', 'bitrate': '0', 'isfuzzy': '0', 'inputtype': '0', 'platform': 'WebFilter', 'userid': '2078452878', 'iscorrection': '1', 'privilege_filter': '0', 'filter': '10', 'token': '483ef68936faa09268f3a42f7ab7ee31b584a3f155828a100c95fadf7c5ddd1e', 'appid': '1014', 'signature': sign, } response = requests.get(url='https://complexsearch.kugou.com/v2/search/song?', headers=headers, params=datas) callback_dict = re.findall('callback123\((.*)\)', response.text)[0] jsurl = json.loads(callback_dict) fileName = jsurl['data']['lists'][0]['FileName'] eMixSongID = jsurl['data']['lists'][0]['EMixSongID'] return fileName, eMixSongID def download_url(file_name, url_mp3): """ 通过已经获取的mp3文件保存到文件夹中 :param file_name: 音乐名 :param url_mp3: 音乐url(.....mp3) :return: 无 """ response = requests.get(url_mp3) try: with open(f"./music_files/{file_name}.mp3", "wb") as f: f.write(response.content) except: with open(f"./music_files/{int(time.time() * 1000)}.mp3", "wb") as f: f.write(response.content) print(f'{file_name}-----下载成功') def directory_create(): """判断文件是否存在。不存在则创建改文件""" directory = "./music_files" if not os.path.exists(directory): os.makedirs(directory) if __name__ == '__main__': directory_create() # 判断music_flie文件是否存在 music_name = '听说你' audio_id = audio_id_list(music_name) # (苏星婕 - 把回忆拼好给你, 72jrv7fa) file_name = audio_id[0] # 苏星婕 - 把回忆拼好给你 emixsong_id = audio_id[1] # 72jrv7fa time.sleep(2) url_mp3 = fetch_url(emixsong_id) # 获取 ......mp3 download_url(file_name, url_mp3) # 下载保存

本次爬取结束,如果有什么其他问题或不懂可以私信哦~

另外还有GUI渲染过的的exe便携版,想要了解的话可以看下一篇文章



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭