前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >批量爬取某音乐网站的音源

批量爬取某音乐网站的音源

原创
作者头像
小明要加油
发布2023-05-09 08:41:19
7240
发布2023-05-09 08:41:19
举报
文章被收录于专栏:自学的专栏自学的专栏

目录

对一首歌的爬取(方法一)

对一首歌的爬取(方法二)

批量获取音源

需求分析:

目标网站:酷X音乐(涉及版权)

实现目标:嘉宾这首歌的所有音源爬取

代码实现步骤:

  • 1、发送请求,对于目标页面的地址发送请求
  • 2、获取数据:获取服务器返回的响应数据
  • 3、解析数据:提取音源的url地址
  • 4、再次发送请求,对于所获取的地址返回响应数据
  • 5、再次获取数据,获取服务器的响应数据
  • 6、解析数据,获取filename、filehash、fileid
  • 7、发送请求,对于音乐数据包发送请求
  • 8、获取数据,获取服务器的响应数据
  • 9、解析数据,提取音乐的url地址
  • 10、保存数据

查看网页

通过浏览网页源代码我们可以判断,网页数据是动态加载,还是我们所要获取的数据就在源代码当中,本文中所介绍的XX音乐的音源数据是属于动态加载,我们打开开发者工具,在搜索框中搜索**mp3**,点击**Priview**选项,可以找到我们所要爬取的所有数据,列表页图解如下:

一首歌曲的爬取(方法一)

打开目标页面,按**F12**进入开发者工具,点击**network**中的**Media**,我们可以看到在页面音源没有被播放的时候,**media**中是空的,当我们按下播放键之后,页面会刷新一个响应数据,此时我们双击该响应值,就会自动播放我们的目标歌曲,点击**Headers**,复制**Request URL**:在新的页面打开,也可以播放目标歌曲。图解如下:

找到响应的url后,此时我们可以很简单的就获取到我们想要下载的音乐

代码语言:javascript
复制
url = 'https://webfs.ali.kugou.com/202305080952/93fcfdc0f574c7773ce4596a0f084ef4/KGTX/CLTX003/44c6970389ea89c74c664448a079374a.mp3'
res = requests.get(url,headers=headers)
with open('./music.mp3','wb')as f:
    f.write(res.content)

一首歌的爬取(方法二)

当我们浏览歌曲详情页面时,打开开发者工具,在搜索框中搜索mp3,可以找到到歌曲的详情数据,我们可以查看该选项的url,可以发现此时的url是由很多的参数拼接成的,而在**payload**中可以找到相应的参数,我们爬取一首歌的情况下,可以直接复制Url,不用设置param中的参数

代码语言:javascript
复制
url = 'https://complexsearch.kugou.com/v2/search/song?callback=callback123&srcappid=2919&clientver=1000&clienttime=1683514972503&mid=1de90ed5784632bd8408190ba329e30e&uuid=1de90ed5784632bd8408190ba329e30e&dfid=11S2Y02tkykk1pCgJ50d89i5&keyword=%E5%98%89%E5%AE%BE&page=1&pagesize=30&bitrate=0&isfuzzy=0&inputtype=0&platform=WebFilter&userid=0&iscorrection=1&privilege_filter=0&filter=10&token=&appid=1014&signature=e448d282c403d24c32183b97de601e85'
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36',
           'Cookie':'kg_mid = 1de90ed5784632bd8408190ba329e30e;kg_dfid = 11S2Y02tkykk1pCgJ50d89i5;kg_dfid_collect = d41d8cd98f00b204e9800998ecf8427e;Hm_lvt_aedee6983d4cfc62f509129360d6bb3d = 1683459911, 1683509659;kg_mid_temp = 1de90ed5784632bd8408190ba329e30e;Hm_lpvt_aedee6983d4cfc62f509129360d6bb3d = 1683523404',
           'Referer':'https: // www.kugou.com /'
}
res = requests.get(url,headers=headers)
# # print(res.text)

写到这里的时候,使用json.loads将json格式的数据转换成python数据,我发现运行以后会有报错

loads() 传的是python的dict字典类型,而我们刚刚传递的类型不符合,所以报错了,此时我们打印一下res.text,发现输出的内容除了我们的目标数据,还多了jQuery191033221067126349535_1683528994015();这组数据将我们的目标数据括起来了,使得输出的数据不是完整的json数据,那么只要我们把多出的部分替换成空就好了

此时我们就得到了我们想要获取的音源地址,在请求该地址,再保存文件即可,流程和方法一一样,我就不过多的赘述了。

批量获取目标数据

上面我们已经实现了对一首歌的爬取,那么我们如何实现对多首歌曲的获取呢,前面在查看网页的时候我们已经介绍到了,网页数据是动态加载的,没有在源码中,我们在搜索框中搜索mp3,会出现相应的符合条件的响应对象,我们可以在**priview**的**data**中找到歌曲列表的数据,如图所示:

那么我们如何通过列表页面,获取到歌曲详情页面的音源数据呢,继续查看网页,前面我们说到,歌曲详情页面的Url地址是由以下几个参数拼接成的:

我们可以多看几个详情页,发现**callback**、和**encode_album_audio_id**,这两个参数是会发生变化的,而最后一个参数实际上是一个时间戳,也就是当前浏览页面的时间,而callback中变化的参数实际上是一个时间计时,后续我们可以用time库来处理,自己创造一个时间计时来表示访问时间,而encode_album_audio_id可以在列表页中找到,它对应的就是列表页中,lists下的**EMixSongID**

也就是说其他的不变的参数,我们可以直接复制粘贴,写在param中,那么我们实际要请求的地址就可以是https://wwwapi.kugou.com/yy/index.php?+ 上面介绍的参数。

此时我们整体思路就清晰了:

1、对列表页请求获取data下的Lists中的**EMixSongID**和**FileName**,也可以获取hash,以前url中是写有hash值的,但是现在请求地址中没有了,所以这里我们只获取两个数值。

2、把获取到的id值和其他参数一起写在data{}字典中,再请求详情页的url,获取mp3音源地址

3、请求获取的音源地址,保存音源

第一步:

获取列表页data下的Lists中的**EMixSongID**和**FileName*

代码语言:javascript
复制
url = 'https://complexsearch.kugou.com/v2/search/song?callback=callback123&srcappid=2919&clientver=1000&clienttime=1683514972503&mid=1de90ed5784632bd8408190ba329e30e&uuid=1de90ed5784632bd8408190ba329e30e&dfid=11S2Y02tkykk1pCgJ50d89i5&keyword=%E5%98%89%E5%AE%BE&page=1&pagesize=30&bitrate=0&isfuzzy=0&inputtype=0&platform=WebFilter&userid=0&iscorrection=1&privilege_filter=0&filter=10&token=&appid=1014&signature=e448d282c403d24c32183b97de601e85'
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36',
           'Cookie':'kg_mid = 1de90ed5784632bd8408190ba329e30e;kg_dfid = 11S2Y02tkykk1pCgJ50d89i5;kg_dfid_collect = d41d8cd98f00b204e9800998ecf8427e;Hm_lvt_aedee6983d4cfc62f509129360d6bb3d = 1683459911, 1683509659;kg_mid_temp = 1de90ed5784632bd8408190ba329e30e;Hm_lpvt_aedee6983d4cfc62f509129360d6bb3d = 1683523404',
           'Referer':'https: // www.kugou.com /'
}
res = requests.get(url,headers=headers)
# # print(res.text)
data = res.content.decode('utf-8')
data = re.sub('callback123\(','',data)
data = re.sub('\)','',data)
# # print(data)
html = json.loads(data)['data']['lists']
# # print(type(html))
for i in html:
  filename = i.get('FileName')
  filehash = i.get('FileHash')
  fileid = i.get('EMixSongID')

第二步

把获取到的id值和其他参数一起写在data{}字典中,再请求详情页的url,获取mp3音源地址

前面我们讲到callback的参数变化使用time库中的time函数解决,我们可以对比几个详情页,发现jQuery1910后的几个数字是变化的,'_'后的16835这几个数字是不变的

代码语言:javascript
复制
 'callback': 'jQuery1910{}'.format(math.floor(time.time()*1000))+'_16835{}'.format(math.floor(time.time()*1000))'

第三步

请求获取的音源地址,保存音源

代码语言:javascript
复制
for h in html_box:
     res_h = requests.get(url=h,headers=headers)
     with open('./{}.mp3'.format(filename),'wb')as f:
         f.write(res_h.content)

列表页的音源我们就获取到啦!!!!!

如果是要爬取多个页面的音源,可以浏览几个页面的url的不同之处,再具体问题具体分析具体解决

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云开发 CLI 工具
云开发 CLI 工具(Cloudbase CLI Devtools,CCLID)是云开发官方指定的 CLI 工具,可以帮助开发者快速构建 Serverless 应用。CLI 工具提供能力包括文件储存的管理、云函数的部署、模板项目的创建、HTTP Service、静态网站托管等,您可以专注于编码,无需在平台中切换各类配置。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档