一、分析网站结构,寻找音频实际下载地址
随便找个免费听的音频列表:https://www.ximalaya.com/youshengshu/12576446/
可以看到结构很明显,a标签里的title是章节名,href属性是章节链接
我们点进去一篇看看,选中Media 发现没有我们需要的音频文件,那是因为音频没播放
点播放后出现了实际地址, 3个都一样内容
将该地址放入网址
https://audio.cos.xmcdn.com/group38/M03/33/B0/wKgJo1qCiJfh31OVADfpIBp6vqM985.m4a
成功播放。 先别高兴太早~ 这只是一个音频地址 我想下载列表全部地址咋办呢??
-----------------------------------------------------------------------------------------------------------------------
此时有2个办法找下载地址的出处, 它是怎么来的
1.第一种
找到看起来像是唯一的标识 比如 音频下载地址中的 wKgJo1qCiJfh31OVADfpIBp6vqM985 去搜索全局
找到一个请求,看它的请求结果Response
请求头:
请求头:https://www.ximalaya.com/revision/play/v1/audio?id=67064624&ptype=1
请求结果:{"ret":200,"data":{"trackId":67064624,"canPlay":true,"isPaid":false,"hasBuy":true,"src":"https://audio.cos.xmcdn.com/group38/M03/33/B0/wKgJo1qCiJfh31OVADfpIBp6vqM985.m4a","albumIsSample":false,"sampleDuration":135,"isBaiduMusic":false,"firstPlayStatus":true}}
果然是的 一段json数据里 有音频下载地址
2.第二种
不选择Media 选中All 显示全部请求,再去播放音频
你会看到多出这些请求, 一个个点进去看Response ,你会发现
它的请求结果是一段json内容 和方法1一样
请求结果:{"ret":200,"data":{"trackId":67064624,"canPlay":true,"isPaid":false,"hasBuy":true,"src":"https://audio.cos.xmcdn.com/group38/M03/33/B0/wKgJo1qCiJfh31OVADfpIBp6vqM985.m4a","albumIsSample":false,"sampleDuration":135,"isBaiduMusic":false,"firstPlayStatus":true}}
data下的src就是实际下载地址 。
-----------------------------------------------------------------------------------------------------------------------
OK 前后都串联起来了
音频下载地址json数据的请求接口:https://www.ximalaya.com/revision/play/v1/audio?id=67064624&ptype=1
当前章节的链接:https://www.ximalaya.com/youshengshu/12576446/67064624
主页列表下的章节链接:/youshengshu/12576446/67064624
其中 12576446 音频ID 67064624是章节ID
思路有了!!!
1.在主页循环获取所有章节ID拼接成音频下载的请求链接
2.请求下载接口获取json数据
3.提取json数据中的实际下载地址,请求它,转为二进制保存到本地 格式mp4
二、确定思路,开始敲代码
现在代码敲起来就很明确,直接上源码,就不一点点说是怎么敲的啦,有注释
模块有点多,用tkinter画了个界面方便操作。 下面有源码+成品的下载地址
import requests #数据挖掘
from lxml import etree #数据清洗
import time
import json
import tkinter #TK界面
import sys # 用来控制程序关闭
import os #文件
import threading #线程
headers={
"User-Agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36"
}
def createUI():
MainInterface = tkinter.Tk() #初始化界面
MainInterface.title("喜马拉雅音频下载器 QQ463392823")
MainInterface.geometry('600x200')
label1=tkinter.Label(MainInterface,text='').grid(row=0,column=0) #间隔符
#创建标签
label1=tkinter.Label(MainInterface,text='音频列表网址:',bg='pink',font=('Arial',12),width=12,heigh=1)
label1.grid(row=1,column=0) #放置标签
global mp4url
#单行输入文本
mp4url=tkinter.Entry(MainInterface,width=50)
mp4url.grid(row=1,column=1)
label1=tkinter.Label(MainInterface,text='').grid(row=2,column=0) #间隔符
#创建按钮
button1=tkinter.Button(MainInterface,text='开始下载',bg='yellow',font=('Arial',14),command=qd)
button1.grid(row=3,column=1)
button2=tkinter.Button(MainInterface,text='停止下载',bg='yellow',font=('Arial',14),command=enddown)
button2.grid(row=4,column=1)
label1=tkinter.Label(MainInterface,text='保存的路径=> c:/喜马拉雅下载').grid(row=5,column=1)
label1=tkinter.Label(MainInterface,text='').grid(row=6,column=0) #间隔符
MainInterface.mainloop() #循环显示界面
'''
音频详情页地址
https://www.ximalaya.com/youshengshu/12576446/67064624
https://www.ximalaya.com/youshengshu/12576446/67064625
https://www.ximalaya.com/youshengshu/12576446/67064626
音频地址json信息
https://www.ximalaya.com/revision/play/v1/audio?id=67064624&ptype=1
https://www.ximalaya.com/revision/play/v1/audio?id=67064625&ptype=1
https://www.ximalaya.com/revision/play/v1/audio?id=67064626&ptype=1
实际下载地址
https://audio.cos.xmcdn.com/group44/M0B/9D/3F/wKgKkVsI3Qqx5Y4iAD5LfSCEmC8942.m4a
'''
def enddown():
sys.exit(0)
def qd():
print("开启线程执行任务")
t1 = threading.Thread(target=stadown)
t1.setDaemon(True)
t1.start()
# 通过音频列表 获取所有音频实际下载链接
def stadown():
# 下载一个音频
res=requests.get(mp4url.get(),headers=headers)
# print(res.text)
html=etree.HTML(res.text)
data = html.xpath('//div[@class="text _Vc"]/a')
for i in data:
# print(i.get('title'))
# print(i.get('href'))
title = i.get('title')
# 通过ID 拼接实际下载地址的json信息
downurl='http://www.ximalaya.com/revision/play/v1/audio?id=' + i.get('href').split('/')[3] + '&ptype=1'
# print(downurl)
res=requests.get(downurl,headers=headers)
# print(res.text)
# 获取实际下载地址
src = json.loads(res.text)["data"]["src"]
print('正在下载'+title)
mp4code=requests.get(src,headers=headers).content
file=open("C:\\喜马拉雅下载\\"+title+".mp4","wb")
file.write(mp4code)
file.close()
time.sleep(3)
#检测目录
def jcos():
dirs='c:/喜马拉雅下载'
if not os.path.exists(dirs): #不存在则创建
os.makedirs(dirs)
jcos()
createUI()
源码+成品链接:https://download.csdn.net/download/qq_18816201/12318891