网页音频抓取(玩转西藏【旅游攻略】的过程实现过程定义一个类)
优采云 发布时间: 2022-03-19 13:25网页音频抓取(玩转西藏【旅游攻略】的过程实现过程定义一个类)
前言
眼睛习惯看文字,累了,转身用耳朵听世界。Himalaya FM,这里是我们想听的,用爬虫抓取我们想要的音频!这次要抢的是关于玩西藏[旅游攻略]的游记,感受高原风情,废话不多说。
环境
win10+python3.7+sublime text
指导包
导入请求---->网页请求和数据抓取
import json--->数据格式转换
from multiprocessing.pool import pool---->使用线程池
网页分析
,URL对应上图,下面是我们要查看的内容的地址。我们主要是把这些音频全部抓取到本地保存,但是我们并没有从这个地址抓取音频的src,而是直接在旅游文章上点击播放来播放西藏【旅游攻略】。在这个过程中,使用浏览器的开发者工具来获取相关信息的json数据。trackAudioPlay 字段收录我们想要的所有音频数据。需要实现以下代码。
抓包过程
定义一个类,在这个类中初始化请求头和请求的资源url,然后在requests对象中使用get()方法,因为网页的请求方法是get方法,然后判断对应的状态码,如果是200,则表示请求成功,然后对获取的内容进行解码。
def __init__(self,num,id):
self.headers={
'Host': 'www.ximalaya.com',
'Referer': 'https://www.ximalaya.com/lvyou/',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36'
}
# albumId=5656303是该收听节目的id,页码:pageNum,一页多少条:pageSize=30
self.url='https://www.ximalaya.com/revision/play/album?albumId='+str(id)+'&pageNum='+str(num)+'&pageSize=30'
def get_content(self):
response=requests.get(url=self.url,headers=self.headers)
# 判断响应的状态码
if response.status_code==200:
# 解码
return response.content.decode()
将获取的字符串数据转换成字典格式,方便获取里面的具体内容,获取相关的音频数据
def get_tracks(self,content):
try:
if content:
# 字符串转换为字典:json.loads()
# print(json.loads(content)['data']['tracksAudioPlay']),测试输出
return json.loads(content)['data']['tracksAudioPlay']
except Exception as e:
print(e)
pass
根据音频连接src重新请求资源,并下载到本地,其中trackName字段中的数据作为每个音频的名称,拼接字符串,更改扩展名为 .m4a 格式,并且在 Windows 系统中,文件名不能有一些特殊的字符串,如 | 和其他特殊字符,所以需要用特殊字符替换trackName字段的字符串数据。
def down_from_src(self,src,trackName):
response=requests.get(url=src)
if response.status_code==200:
# 去除特殊符号,因为windows的文件不能出现这些特殊字符
trackName=trackName.replace('|','').replace('?','').replace(':','').replace(' ','')
with open(trackName+'.m4a','wb') as f:
f.write(response.content)
需要判断url,因为对于vip音频,这里的url是空的,不存在的,所以无法直接抓取数据。
# 程序主入口
def main(i):
sipder=xizangSipder(i,5656303)
for tracksAudioPlay in sipder.get_tracks(sipder.get_content()):
try:
src,trackName=tracksAudioPlay['src'],tracksAudioPlay['trackName']
if src:
sipder.down_from_src(src,trackName)
except Exception as e:
print(e)
pass
if __name__=='__main__':
# 创建线程池
pool=Pool(5)
# 第一个参数是函数,第二个参数是一个迭代器,把迭代器的数字作为参数传进去
pool.map(main,[x for x in range(1,7)])
# 关闭线程池
pool.close()
# 主线程阻塞等待子线程的退出
pool.join()
达到效果
渲染(抓取 6 页音频)
总结:程序比较简单。只要知道资源连接在哪里,就可以通过资源url抓取,通过线程池提高程序效率。音频下载的VIP版还没有实现,下一步就是实现了(但是这样破解别人的VIP是违法的,小心点!)
项目链接:链接:提取码:b78t