python爬虫实战练习 --- 喜马拉雅免费音频 下载到本地

一、分析网站结构,寻找音频实际下载地址

        随便找个免费听的音频列表: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

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章