蜻蜓fm下载路径(蜻蜓fm有声书批量下载)

首页教程更新时间:2023-05-17 23:38:13

目标站点 有声小说-有声读物-电台广播在线听书-蜻蜓FM

python爬虫实战搞的是PC端,移动端可能有更加方便的接口,欢迎大家留意讨论反正是练手就随便抓一下pc端的包好了


主要内容


这个例子的登录非常简单没有任何加密直接post就行真的是一点加密和未知参数都没有

私信小编01即可获取大量python学习资源

蜻蜓fm下载路径,蜻蜓fm有声书批量下载(1)


python实现,注意此处是类的一个方法不完整无法直接运行

def login(self,user_id,password): data = { 'account_type': '5', 'device_id': 'web', 'user_id': user_id, 'password': password } response = self.session.post(self.login_url,data=data) if response.status_code==200: temp = response.json() errorno = temp['errorno'] errormsg = temp['errormsg'] if errorno == 0: print('login successful!','登录成功!') data = temp['data'] self.qingting_id = data['qingting_id'] self.access_token = data['access_token'] else: print('Login failed','登录失败') print(errormsg)

录成功后我们把access_token和qingting_id拿到,相当于一个登录后的标志如果账号是会员相当于一个会员标志
音频的真实地址请求了这样一个url:

https://audio.qingting.fm/audiostream/redirect/294280/11604885


其中294280是专辑id,
11604885是当前音频的id

蜻蜓fm下载路径,蜻蜓fm有声书批量下载(2)

其中还带了一些参数比如access_token,qingting_id(登录成功的response中有,上图没有登录所有是空的),另外还有一些比如t是时间戳,


device_id=MOBILESITE(不变)


关键就在于sign(尝试过不加sign会返回一个签名错误)


可以通过全局搜索试一下是哪个js生成的这个sign我全局搜索了一下


device_id


mian.一大堆.js 找到了生成sign的函数(需要自己分辨一下是一个device_id: "MOBILESITE"的)


搜索其他关键字应该也是可以顺利找到的

蜻蜓fm下载路径,蜻蜓fm有声书批量下载(3)

这里的sign是u这个变量它是由c这个变量通过一堆加密处理得到的


我们可以控制台输出一下u和c

蜻蜓fm下载路径,蜻蜓fm有声书批量下载(4)

所以我们就知道了sign实际是加密了请求的其他参数


一开始我误以为是单纯的MD5所以卡了好久(还进入函数内部看他具体是怎么实现的看的一头雾水)


其实代码已经告诉用的是


createHmac("md5", "fpMn12&38f_2e")

查了下Hmac发现就是一种现成的算法,还有不同的模式MD5是其中一种,需要一个秘钥


这里什么都告诉你了,用Hmac-md5秘钥是fpMn12&38f_2e


找个在线加密的网站试了下,果然和刚才控制台输出的一样

蜻蜓fm下载路径,蜻蜓fm有声书批量下载(5)

python的话需要import


hmac这个库

import hmac import time base_url = "https://audio.qingting.fm" bookid = "294280" id = "11590788" access_token = "" qingting_id ="" timestamp = str(round(time.time()*1000)) data = f"/audiostream/redirect/{bookid}/{id}?access_token={access_token}&device_id=MOBILESITE&qingting_id={qingting_id}&t={timestamp}" message = data.encode('utf-8') key = "fpMn12&38f_2e".encode('utf-8') sign = hmac.new(key, message, digestmod='MD5').hexdigest() whole_url = base_url data "&sign=" sign print(whole_url)

得到一个音频可以做到了剩下的就是得到一堆了,其实我们得到每个音频的id就可以了

我请求的是这个接口

info_api = 'https://i.qingting.fm/capi/channel/{self.bookid}/programs/{self.version}?curpage={str(page)}&pagesize=30&order=asc'


version在声书主页的源代码中,只要改curpage就可以翻页了 完整源码

import requests import re import hmac import time from tqdm import tqdm from bs4 import BeautifulSoup import os import json import sys import urllib3 urllib3.disable_warnings() class QingTing(): def __init__(self,user_id,password,bookurl,ifLogin): self.ifLogin = ifLogin self.user_id = user_id self.password = password self.session = requests.session() self.session.headers.update({'user-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36'}) self.login_url = "https://u2.qingting.fm/u2/api/v4/user/login" self.qingting_id = '' self.access_token = '' self.bookurl = bookurl # self.bookurl = 'https://www.qingting.fm/channels/257790' self.bookid = self.bookurl.split('/')[-1] self.version = '' self.qingtinghost = 'https://audio.qingting.fm' self.save_path = '' self.bookname = '' def login(self,user_id,password): data = { 'account_type': '5', 'device_id': 'web', 'user_id': user_id, 'password': password } response = self.session.post(self.login_url,data=data,verify=False) if response.status_code==200: temp = response.json() errorno = temp['errorno'] errormsg = temp['errormsg'] if errorno == 0: print('login successful!','登录成功!') data = temp['data'] self.qingting_id = data['qingting_id'] self.access_token = data['access_token'] else: print('Login failed','登录失败') print(errormsg) time.sleep(10) sys.exit(0) def __get_version(self): response = self.session.get(url=self.bookurl,verify=False) if response.status_code==200: soup = BeautifulSoup(response.text,'lxml') temp_bookname = soup.select('div.album-info-root > div.top > div.info.right > h1')[0].string replaced_pattern = '[\\\/:\*\?\"<>|]' self.bookname = re.sub(replaced_pattern,' ',temp_bookname,flags=re.M re.S) if not os.path.exists(self.bookname): os.makedirs(self.bookname) matched = re.search('\"version\":\"(\w )"',response.text,re.S) if matched: version = matched.group(1) self.version = version # return version def __get_total_page(self): self.__get_version() page = 1 info_api = f'https://i.qingting.fm/capi/channel/{self.bookid}/programs/{self.version}?curpage={str(page)}&pagesize=30&order=asc' response = self.session.get(info_api,verify=False) if response.status_code==200: temp = response.json() total = temp['data']['total'] total_page = int(int(total)/30) 1 return total,total_page def get_book_info(self): total,total_page = self.__get_total_page() print(self.bookname,'共{}集'.format(total)) for page in range(1,total_page 1): info_api = f'https://i.qingting.fm/capi/channel/{self.bookid}/programs/{self.version}?curpage={str(page)}&pagesize=30&order=asc' response = self.session.get(info_api,verify=False) programs = response.json()['data']['programs'] for program in programs: # print(program['id'],program['title']) yield program def get_src(self,id): bookid = self.bookid access_token = self.access_token qingting_id =self.qingting_id timestamp = str(round(time.time()*1000)) data = f"/audiostream/redirect/{bookid}/{id}?access_token={access_token}&device_id=MOBILESITE&qingting_id={qingting_id}&t={timestamp}" message = data.encode('utf-8') key = "fpMn12&38f_2e".encode('utf-8') sign = hmac.new(key, message, digestmod='MD5').hexdigest() whole_url = self.qingtinghost data "&sign=" sign return whole_url def downloadFILE(self,url,name): resp = self.session.get(url=url,stream=True,verify=False) if resp.headers['Content-Type'] =='audio/mpeg': content_size = int(int(resp.headers['Content-Length'])/1024) with open(name, "wb") as f: print("Pkg total size is:",content_size,'k,start...') for data in tqdm(iterable=resp.iter_content(1024),total=content_size,unit='k',desc=name): f.write(data) print(name , "download finished!") else: errorno = resp.json()['errorno'] errormsg = resp.json()['errormsg'] print('没有权限下载,请登录已购此音频的账号。') print('errorno:',errorno,errormsg) def run(self): if self.ifLogin: self.login(self.user_id,self.password) programs = self.get_book_info() count = 0 for program in programs: count =1 try: id = program['id'] title = str(count).zfill(4) ' ' program['title'] '.m4a' if not self.bookname =='': title = os.path.join(self.bookname,title) whole_url = self.get_src(id) self.downloadFILE(whole_url,title) except Exception as e: print(e) with open('log.txt','a',encoding='utf-8') as f: f.write(str(count) str(e) '\n') def get_config_info(): with open('config.json','r',encoding='utf-8') as f: config = json.loads(f.read()) return config if __name__ == "__main__": # pyinstaller -F -i ico.ico QingTingFM.py config = get_config_info() if config["ifLogin"]: bookurl = input('请输入要下载音频的主页链接:(如[url=https://www.qingting.fm/channels/257790]https://www.qingting.fm/channels/257790[/url])') isvalid = re.search('https://www.qingting.fm/channels/\d ',bookurl) if isvalid: q = QingTing(config["user_id"],config["password"],bookurl,1) q.run() else: print("输入的主页格式错误") else: # 不登录 bookurl = input('请输入要下载音频的主页链接:(如[url=https://www.qingting.fm/channels/257790]https://www.qingting.fm/channels/257790[/url])') isvalid = re.search('https://www.qingting.fm/channels/\d ',bookurl) if isvalid: q = QingTing(config["user_id"],config["password"],bookurl,0) q.run() else: print("输入的主页格式错误")

配置文件部分

{ "ifLogin":1, "user_id":"135########", "password":"pwd########" },

图文教程
相关文章
热门专题
推荐软件
奇热小说
奇热小说
下载
QQ2019手机版
QQ2019手机版
下载
王者荣耀
王者荣耀
下载
百度浏览器迷你版
百度浏览器迷你版
下载
2345浏览器手机版
2345浏览器手机版
下载
网易邮箱
网易邮箱
下载
爱奇艺
爱奇艺
下载
网易云音乐
网易云音乐
下载
WPSOffice
WPSOffice
下载
优酷
优酷
下载
谷歌浏览器(Chrome)
谷歌浏览器(Chrome)
下载
迅雷看看播放器
迅雷看看播放器
下载
UC浏览器
UC浏览器
下载
QQ音乐
QQ音乐
下载
阿里旺旺买家版v9.12.10C官方版
阿里旺旺买家版v9.12.10C官方版
下载
360安全卫士v12.1官方版
360安全卫士v12.1官方版
下载
猜你喜欢
东电云视转发端v1.0.24.0官方版
东电云视转发端v1.0.24.0官方版
下载
美国警察怪兽德比
美国警察怪兽德比
下载
WiFi流量监控(WifiChannelMonitor)v1.59绿色版
WiFi流量监控(WifiChannelMonitor)v1.59绿色版
下载
LightX
LightX
下载
QQ阅读iPad版v6.5.80
QQ阅读iPad版v6.5.80
下载
增强Windows用户管理器v1.0绿色版
增强Windows用户管理器v1.0绿色版
下载
天天拍车app
天天拍车app
下载
美美天气通
美美天气通
下载
豪华消星星红包版
豪华消星星红包版
下载
WildPacketsOmniPeekV4.1
WildPacketsOmniPeekV4.1
下载
新浪新闻极速版iOS
新浪新闻极速版iOS
下载
欢乐块队
欢乐块队
下载
Ninebot(九号平衡车app)v2.1.9
Ninebot(九号平衡车app)v2.1.9
下载
XBOX360动物园大亨GOD
XBOX360动物园大亨GOD
下载
亿个宝
亿个宝
下载
宁波原水
宁波原水
下载