今天爬取的是喜马拉雅有声小说。
目标网址:https://www.ximalaya.com/youshengshu/
分析操作开始:
首先在喜马拉雅有声小说页面,播放任意音频。
当播放音频时,打开抓包工具(加载网页后打开抓包工具,发现没有抓到数据包,刷新网页就行),这边选择媒体Media,一般的视频,音频文件都会在这里被抓取到。
下图就是抓到的音频文件。
我们尝试访问一下该接口的url,将url复制到浏览器打开。
发起访问后,跳转出了一个保存文件到本地的界面。
我们选择保存,发现多了一个类型为M4A的文件。
尝试播放,发现的确是之前在喜马拉雅界面中播放的有声小说音频。
通过上述操作,我们明白访问该url可直接得到相应的音频文件。
现在开始分析这个url
“https://aod.cos.tx.xmcdn.com/group58/M09/4B/2B/wKgLc1zJeDKgmWlwADxJRm7KRfE151.m4a”
一看就可以看到 这个url上全是各种加密
如果我们直接去做解密的话,这是不合适的,因为同样我们也不知道它是否真的是加密了,有可能他只是在26个英文字母和0到9个阿拉伯数字随机组成呢。
咱们不确定它是哪种加密方式,那么怎么办呢?
我们先复制他
然后在所有抓到的包中 去寻找
搜索后我们发现 出现了一个audio音频接口
我们双击后发现控制台返回的一大串数据里面数据里面有一个叫src的,就有我们刚刚看到的音频数据。
也就是说 音频是这样生成的 并不是一个加密
我们找到它的url地址以后 去访问
访问后发现他是类似于一个字典一样的储存,并且包含着刚刚的src数据,就是有声小说音频播放的地址。
整理一下思路,也就是我们可以请求这个接口然后得到一大串数据,我们在得到的一大串数据中 再提取src链接,也就是音频地址。
准备开始怼代码了,我们先创建一个py文件 和 一个存放音频数据的文件夹。
常规的基础爬虫请求,请求方式为get请求。
请求结果如下,控制台打印的数据为两个字典嵌套。
通过简单的处理,再次打印数据。
成功打印出音频文件的地址!!
这个时候我们就已经可以存储文件了,因为地址已经拿到了,但是存储文件 文件名是必不可少的,咱们回忆之前下载的音频文件。
简单思索一下 我们其实可以直接将src这个网址的末尾,作为音频文件的文件名。
通过基础的字符串切割,得到音频文件名字。
再次进行常规爬虫操作,对srd的地址发起请求。
得到16进制的,字节数据。
最后只需要进行文件存储,就可以将音频文件保存到本地了。
这个时候一个音频文件的操作已经完成。
但是!!!爬虫的优势是什么????是大批量的下载。
想要大批量的下载,就必须使得url变成动态url。
所以我们再次回到开头,选取另一个音频专辑的url对比参数。看看能不能发现规律。
重复最开始的操作播放音频,通过抓包工具抓到音频文件的接口,复制id进行搜索。
拿到url,进行比对。
比对发现 只是id不一样。那我们可以进行url拼接使得url可以动态变化。
因为我们知道了更换id就可以使得下载音频文件的url变化,下载不同的音频文件,只需要更换url的id,所以我们想办法在专栏下抓取音频文件的id。
静态数据永远比动态数据要好拿一点,我们先看看静态页面上有没有我们想要的数据。
果然不出我们所料,id就藏在这些静态数据当中。
进行简单爬虫操作,获得页面源码。
上图的url错误了,应该是某个有声小说专辑的url,而不是整个有声小说的url。正确url应该为“https://www.ximalaya.com/youshengshu/40942749/”)
为了保证数据的准确性,我们通过浏览器,截取一段页面源码,然后在pycharm打印台搜索,测试是否拿到了真实的页面源码。
在获取到的数据中搜索,成功搜索到了匹配的内容,证明我们的确获得到了 页面的真实源码。
抓取id,用它的类选择器。
完美!成功打印出之前所需要的id。
这时仔细的同学应该已经发现,每个章节的音频名字就在id的旁边。
我们顺手再降名字也一起抓取。
参数都拿到了,我们将之前保存音频的代码封装成一个函数。
然后将刚刚拿到的,name和id传过去。为了保证准确性中途可以多次打印来测试。
这里整个喜马拉雅爬虫算是完工了,输入这里直接input的专题的url就好了,但是小编发现,输入url后必须敲两个空格再回车,不然会直接从浏览器访问网址了。
因为多输入了两个空格,我们只需要进行简单的字符串操作,再将url传入之前函数里面,我们的爬虫就算是完成了!!!!!!
下面附上源码:
# -*- endoding: utf-8 -*-
# @ModuleName:喜马拉雅
# @Function(功能):
# @Author : 苏穆冰白月晨
# @Time : 2021/3/17 9:52\
"""喜马拉雅音频爬虫"""
import requests
from pyquery import PyQuery as pq #局部搜索
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36'
}
def request_mp3(id, name):
"""保存音频文件"""
url = "https://www.ximalaya.com/revision/play/v1/audio?id={}&ptype=1".format(id)
print(url)
response = requests.get(url,headers=headers).json()
data = response['data']['src']
mp3 = requests.get(data,headers=headers)
f = open('./音频文件/' +name, 'ab' ) #文件路径 文件读写方式 a文件追加(不存在新建) b进制文件
f.write(mp3.content)
f.close()
def main(urls):
response = requests.get(urls,headers=headers).text
doc = pq(response)
"""<a title="神棍下山记 001 如此师徒(免费收听,福利多多,订阅不迷路)" href="/youshengshu/40942749/328847758"><span class="title lF_">神棍下山记 001 如此师徒(免费收听,福利多多,订阅不迷路)</span></a>"""
text1 = doc(".text.lF_ a").items()
for i in text1:
id1 = i.attr("href").split('/')[3]
name = i.attr("title").split('(')[0]
print(id1)
print(name)
request_mp3(id1, name)
if __name__ == '__main__':
urls1 = input(r"请输入专辑的url: ").split(" ")
urls = urls1[0]
main(urls)
如果对您有帮助可以的话关注一下公众号:ALL程序猿