引言
《喜马拉雅》上既有许多有价值的音频,也有许多繁杂无用的时间陷阱。于是,取我所需就成了第一要务,APP就是舍弃的对象。软件上下载了音频,却发现惨遭加密。那么,就爬吧。
分析
1
以此专辑为例,目标是获取音频。
浏览器右键检查,单击网络。此时点击播放一个音频,可以看到出现了一个含有“audio”的文件,
点击标头获取这个文件的“URL”,在浏览器中查找此链接,可看到如下的文本,
其中,src,指向的是一个音频链接,打开后可以知道这就是刚刚播放的音频了。观察获取此文本的链接,其中有参数“377699956”,留意点击的音频,可以发现此数字就是音频的ID。
至此,目标为,获取整张专辑596个ID,由此获取596个音频链接,下载音频。
下面的任务是如何获取音频ID。
2
再来到专辑主页,主页一共有20个Page,分布着596个声音,分析网页源代码,发现其中只能找到第一个Page中的声音。右键检查网络,点击第二个Page、第三个,看到出现了新的文件,
预览之,其中有我们需要的音频ID,还有每个音频的title。
观察此文件的URL:
“https://www.ximalaya.com/revision/album/v1/getTracksList?albumId=31109428&pageNum=2&sort=0”。
其中有参数“albumId”,即专辑ID,有“pageNum”,即20个Page的其一。
至此,音频ID找到,下面编写程序。
爬虫
获取id
import requests
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)'
' Chrome/96.0.4664.110 Safari/537.36 Edg/96.0.1054.62'
}
id_pages = [f'https://www.ximalaya.com/revision/album/v1/getTracksList?albumId=31109428&pageNum={i}&sort=0' for i in range(1, 21)] # 20个包含ID的page页面
# 存放id与title的列表
audio_id = []
titles = []
for url in id_pages:
resp = requests.get(url, headers=headers)
tracks = resp.json()['data']['tracks']
for track in tracks:
id = track['trackId']
title = track['title']
audio_id.append(id)
titles.append(title)
获取音频链接
audio_pages = [f'https://www.ximalaya.com/revision/play/v1/audio?id={id}&ptype=1' for id in audio_id] # 596个音频信息页
audio_urls = []
for url in audio_pages:
resp = requests.get(url, headers=headers)
audio_url = resp.json()['data']['src']
audio_urls.append(audio_url)
下载音频
for i in range(596):
title = titles[i]
url = audio_urls[i]
with open(f'D:/videos/Verbal Advantage/{title}.m4a', 'wb') as fo:
fo.write(requests.get(url, headers=headers).content)
print(f'"{title}" is ok!')
全部代码
import requests
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)'
' Chrome/96.0.4664.110 Safari/537.36 Edg/96.0.1054.62'
}
id_pages = [f'https://www.ximalaya.com/revision/album/v1/getTracksList?albumId=31109428&pageNum={i}&sort=0' for i in range(1, 21)]
audio_id = []
titles = []
for url in id_pages:
resp = requests.get(url, headers=headers)
tracks = resp.json()['data']['tracks']
for track in tracks:
id = track['trackId']
title = track['title']
audio_id.append(id)
titles.append(title)
audio_pages = [f'https://www.ximalaya.com/revision/play/v1/audio?id={id}&ptype=1' for id in audio_id]
audio_urls = []
for url in audio_pages:
resp = requests.get(url, headers=headers)
audio_url = resp.json()['data']['src']
audio_urls.append(audio_url)
for i in range(596):
title = titles[i]
url = audio_urls[i]
with open(f'D:/videos/Verbal Advantage/{title}.m4a', 'wb') as fo:
fo.write(requests.get(url, headers=headers).content)
print(f'"{title}" is ok!')