在podcast的itunes store上看到了一些有趣的音频,于是突发奇想把它下载下来,比如:郭德纲相声全集
废话少说,先上代码
import requests
import xml.dom.minidom
import os
import urllib
import subprocess
import random
import time
# Podcast的XML地址
url = "http://www.ximalaya.com/album/9977848.xml"
# 仿冒Chrome浏览器进行访问,否则会无法访问
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
response = requests.get(url, headers=headers)
# 对获取的XML进行分析
full_xml = response.text
DOMTree = xml.dom.minidom.parseString(full_xml)
collection = DOMTree.documentElement
items = collection.getElementsByTagName("item").__reversed__()
# 创建存放文件的文件夹
if not os.path.exists('download'):
os.makedirs('download')
if not os.path.exists('mp3'):
os.makedirs('mp3')
# 逐一下载文件
for item in items:
title = item.getElementsByTagName('title')[0].childNodes[0].data
url = item.getElementsByTagName('guid')[0].childNodes[0].data
interval = item.getElementsByTagName('itunes:duration')[0].childNodes[0].data
# 下载下来的文件以标题进行重命名
filename = "download/"+title+".m4a"
with urllib.request.urlopen(url) as web:
with open(filename, 'wb+') as outfile:
outfile.write(web.read())
print(filename,"downloaded")
# 调用ffmpeg将m4a转换为MP3
subprocess.call([
"ffmpeg", "-i", filename,
"-acodec", "libmp3lame", "-ab", "256k",
"mp3/"+title+".mp3"
])
# 这个部分可选
# 仿冒人类行为,停留一个特定时间,免得被拉黑
seconds = interval.split(":")
second = int(seconds[0]) * 60 + int(seconds[1])
wait_time = second * random.uniform(0.04, 0.06)
print("wait", wait_time, "seconds")
time.sleep(wait_time)
代码结构很简单:
- 获取专辑的描述文件,podcast的所有专辑都有一个xml描述文件,要想获取该描述文件,首先需要订阅这个专辑,然后在“资料库”的右侧菜单中选择“拷贝 播客URL”,这时候xml文件就在剪贴板中了,将它复制到代码中:
url = "http://www.ximalaya.com/album/9977848.xml"
,郭老师的这个专辑其实是放在喜马拉雅的; - 分析描述文件,不难发现,每一个xml中包含很多个item,每个item对应一个节目,逐个下载就行了;
- 部分网站对直接下载做了反爬取,本例中,喜马拉雅对浏览器类型做了限制,代码中需要指定
User Agent
才能访问XML文件; - 最后,本例还使用了著名的开源转码工具ffmpeg对下载的m4a音频进行格式转换,毕竟大家最常用的还是mp3嘛。
参考文献:
路人:Podcast随时都可以在线听,为什么还要下载?
禅师:你知道《道德经》为什么叫这个名字吗?
路人:为什么?
禅师:老子愿意!