环境:64位win7+Python 3.6+Eclipse+Pydev
分析喜马拉雅格式
以乡村爱情9为例,分析下载路径:
打开连接路径,调用chrome里的开发者工具,(更多工具——>开发者工具)
在页面上点击播放按钮,检查浏览器请求的各项链接,如图所示,在Network里,可以看到“.json”文件,在右侧打开“Preview”,检查里面的代码:
album_title:专辑名称
play_path:音频文件的地址
title:音频文件的名称
这三项,就是我们需要提炼出来的信息。
音频文件下载的步骤,是通过“.json”文件,在本地建立名为“album_title”的文件夹,将下载的音频(路径为play_path)保存名称为“title”后存入该文件夹。
鼠标移至“30543115.json”,右键选择可以看到30543115.json文件的下载地址为:
http://www.ximalaya.com/tracks/30543115.json
在网页源代码上,我们找到下面一项
<div class="personal_body" sound_ids="30543115,30561910,30561911,30561912,30561913,30561914,30561915,30561916,30561917,30561918,30561919,30561920,30561921,30561922,30561923,30561924,30561925,30561926,30561927,30561928,30561929,30561930,30561931,30561932,30561933,30561934,30561935,30561936,30561937,30561938">
可以发现“sound_ids=”内的文件,正好是该专辑下对应的各个音频的.json文件名称
由此,我们可以推出其该专辑其余音频信息文件也在形如
http://www.ximalaya.com/tracks/xxx.json 的文件内
抽取其中一个进行检验,比如30561933,在浏览器打开http://www.ximalaya.com/tracks/30561933.json,发现正如所预料那样,是该专辑某音频的信息
注:直接从浏览器打开,中文字符可能显示为形如”album_title”:”\u4e61\u6751\u7231\u60c59”的样式,需要进行转码,可以利用开发者工具检查该json文件信息。
代码
# -*- coding: utf-8 -*-
#! /usr/bin/env python3
from bs4 import BeautifulSoup
import urllib.request
import json,os
def bsObjForm(url):
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) ' 'Chrome/51.0.2704.63 Safari/537.36'}
req = urllib.request.Request(url=url, headers=headers)
html = urllib.request.urlopen(req).read().decode('gbk','ignore')#, 'ignore'
bsObj1 = BeautifulSoup(html, "lxml")
return bsObj1
def Schedule(a,b,c):
'''''
a:已经下载的数据块
b:数据块的大小
c:远程文件的大小
'''
per = 100.0 * a * b / c
if per > 100 :
per = 100
print ('%.2f%%' % per,'已下载的大小:',a*b,'文件大小:',c)
#print '已经下载的数据块:',a#,'\n'
#print '数据块的大小:',b#,'\n'
#print '远程文件大小:',c,'\n'
#print '已下载的大小:',a*b,'文件大小:',c
#获得专辑信息,分析音频文件名称,所属专辑,下载地址,并将文件保存在本地
def getM4a(url):
bsObj = bsObjForm(url)
soundInfo=bsObj.p.string
jsonStr = json.loads(soundInfo)
album_title=jsonStr['album_title']
play_path=jsonStr["play_path"]
title=jsonStr["title"]
#由于title里面可能包含不能作文件名称的字符,所以将这些字符去掉
title= re.sub('[\/:*?"<>|]','_',title)
print(album_title,play_path,title)
#将单曲写入文件
#判断文件夹是否存在,如果不存在,则新建文件夹
if os.path.exists('../src/喜马拉雅/'+album_title+'/')==False:
os.makedirs(u'../src/喜马拉雅/'+album_title+'/')
article_path='../src/喜马拉雅/'+album_title+'/'+title+'.mp3'
#判断文件是否存在,如果存在,则不进行下载
if os.path.exists(article_path):
print('%s 文件已经存在'%title)
else:
urllib.request.urlretrieve(play_path,article_path,Schedule)
#分析所属专辑内各文件地址
def getAlbumInfo(url):
bsObj = bsObjForm(url)
soundIds=bsObj.find('div', attrs={'class':'personal_body'}).get('sound_ids').split(',')
for soundId in soundIds:
print(soundId)
path_url='http://www.ximalaya.com/tracks/'+soundId+'.json'
print(path_url)
getM4a(path_url)
print('下载完成')
getAlbumInfo('http://www.ximalaya.com/27639105/album/3751131')
运行的时候,调用getAlbumInfo(url)函数,url为喜马拉雅文件的连接