本帖最后由 kiopc 于 2020-10-30 14:07 编辑
前言
很早之前在某博客平台写了一篇爬虫的文章,是突破某音乐站点的收费歌曲限制
写完之后陆陆续续有不少私信我要求使用代码的,也有说代码不能使用求更新的,种种原因一直没有更新
前段时间登录了博客,又有不少私信的,决定再重新更新下
所谓道高一尺魔高一丈,没有谁比谁高,只有谁更高
肝、淦~~
分析
先打开站点搜索界面:
打开音乐,边听边分析,按F12打开开发者工具:
点击小箭头-1,接着将鼠标移动到要观察的部分-2,点击上图中序号为2的部分,这时候会在右边出现红框中的东西,我们发现,在这里是没有该音乐的地址,只有javascript跳转,无法得到我们想要的东西。
由于只有javascript跳转,那我们去js中去寻找线索。
在当前页面右边的开发者工具中,如下图操作:
此时,这里面是没有任何内容的,按F5刷新页面,此时会出现很多js文件,通过观察,最大的可能就是song?callback:
结果不出所料,在这个lists找到了搜索的音乐:someone you loved
点开lists,出现了很多参数,有些能猜到是干嘛的,比如songName,有些不能。
在音乐播放界面,通过开发者工具,找到了歌曲的下载链接,巧合的是在音乐播放页面源码中的data-hash值为播放页链接中的hash值,而album_id在song?callback中也能找到
所以:音乐播放页源码中的data-hash = 音乐播放页链接中的hash = song?callback中的FileHash
此时,在页面中找到了mp3地址,也找到了需要的两个参数:hash 和 album_id
拼接播放页面链接去请求,发现返回结果中没有包含音乐的MP3地址,emm~~
继续吧,继续去js中找线索:
请求下该js的链接:
可以看到,红线部分与播放页面中地址一致,只不过js中加了一些“/”。
分析请求的js链接,其中共六个参数:
[HTML] 纯文本查看 复制代码
&hash=F7FCFD58DE92805394AF33DB40D8229B
&album_id=29445985
&dfid=3dlJOW3MzfDL1AC7vh2e2qnr
&mid=75d4e5233c06caf3feea9493f4a2da7a
&platid=4
&_=1603952447780
前面两个参数是可以在song?callback中的lists中获取到,后面四个参数在测试中发现,只需要mid 和 dfid两个,也就是说获取到MP3的地址只需要四个参数即可:
[HTML] 纯文本查看 复制代码
&hash=F7FCFD58DE92805394AF33DB40D8229B
&album_id=29445985
&dfid=3dlJOW3MzfDL1AC7vh2e2qnr
&mid=75d4e5233c06caf3feea9493f4a2da7a
在分析了多首歌曲,发现后面两个参数是没有变化的,这就好说了,拼接音乐播放页面的js链接就行了。
代码:
[Python] 纯文本查看 复制代码
# encoding=utf-8
# Time : 2020/10/29 12:46
# file : xGou.py
# AuThor : 阿布的进击
# Blog : www.TopAbu.com
import random
import json
import requests
import re
USER_AGENTS = [
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36',
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11',
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36',
'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko',
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2',
]
class XGou(object):
""" xGou音乐"""
def __init__(self):
self.searchUrl = "http://songsearch.topabu.com/song_search_v2?callback=jQuery191034642999175022426_1489023388639" \
"&keyword={}" \
"&page=1" \
"&pagesize=30" \
"&userid=-1" \
"&clientver=" \
"&platform=WebFilter" \
"&tag=em&filter=2" \
"&iscorrection=1" \
"&privilege_filter=0" \
"&_=1489023388641"
self.mp3JsUrl = "https://wwwapi.topabu.com/yy/index.php?r=play/getdata" \
"&callback=jQuery191021676872185506668_1603952447779" \
"&hash={0}" \
"&album_id={1}" \
"&dfid=3dlJOW3MzfDL1AC7vh2e2qnr" \
"&mid=75d4e5233c06caf3feea9493f4a2da7a"
self.headers = {
'User-Agent': random.choice(USER_AGENTS),
"referer": "https://www.topabu.com/",
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.8',
}
def getpages(self, url, headers):
# pages = requests.get(url=url, headers=headers)
return requests.get(url=url, headers=headers).content.decode()
def getparms(self, pages):
return json.loads(pages)
if __name__ == '__main__':
ite = XGou()
url_1 = ite.searchUrl.format('someone you loved')
page_str = ite.getpages(url_1, ite.headers)
# print(page_str)
res = re.findall(r'{"status":1,.+.error_msg":""}', page_str)
jsInfo = json.loads(res[0])
mp3Infos = jsInfo['data']['lists']
for mp3Info in mp3Infos:
fileHash = mp3Info['FileHash']
album_id = mp3Info['AlbumID']
url_2 = ite.mp3JsUrl.format(fileHash, album_id)
res2 = ite.getpages(url_2, ite.headers)
res = re.findall(r'\{"status".+.\}}}', res2)
jsMp3Info = json.loads(res[0])
print(jsMp3Info['data']['play_backup_url'])
break
总结:
因为版权的问题,已将某音乐平台的拼音换成了topabu,拿到代码改回去就可以了。
自定歌曲需要再修改下代码,需要去增加输入功能,并将输入的参数传递给请求的URL。
另外,有一些参数方面的猜想,有可能突破收费限制,但不打算再去找突破限制了,尊重版权、尊重知识付费,算是虎头蛇尾了,Peace~~
感兴趣的可以自己去观察两个链接中的参数传递
这篇文章就当抛砖引玉了,突破了x狗的收费音乐的可以分享一下,感谢 |