Yi's Blog

不图新奇,但问优劣

音悦台MV下载 Python版本

制作过程:

前面写过了一个 GoogleMusic 专辑下载的 Python 版本,这里是下载脚本另一则。

因为前段时间在人人上总能看见音悦台里 MV 的推荐链接,用 Chrome 查看网页加载的文件也可以很容易的找出播放的 MV 的 URL,然后用 wget 轻松下载到本地。既然浏览器能把文件的地址显示出来,用程序也一定可以。

这个过程还是有一点点曲折的:

  • 读 HTML 代码,发现文件的链接是嵌入的 Flash 获取一个 videoId,然后根据 videoId 获取的。
  • 找了一个可以反编译 Flash 文件的软件 SWFDecompiler,反编译了一下 Flash 文件,简单读了一下相关的代码,不是很有头绪,然后决定从 Flash 发起的 HTTP 请求入手。
  • 先用了 Wireshark 尝试抓了一下包,结果发现自己学艺不精,不太会用 Wireshark,找不到链接是怎么来的。
  • 决定找一个相对简单的 HTTP 请求获取的软件,StackOverflow 搜到在 Mac 下有这几个软件可以实现

    我用的是后者,非常好用,简单直接的找到了 URL 所在的 HTTP 请求。

  • Python 脚本发送 HTTP 请求,正则表达式分析出 URL,再从原页面获取 MV 的名字,wget 下载。

代码在这里

# coding=utf-8
from BeautifulSoup import *
import sys, httplib
import re
import os
import urllib,urllib2
def getMVName(url):
c=urllib2.urlopen(url)
soup=BeautifulSoup(c.read())
name=soup.find('h1', id='videoTitle').contents[0]
print name
name = urllib.unquote(name)
return name
if __name__ == '__main__':
headers = {"Content-type": "application/x-www-form-urlencoded","Accept": "text/plain"}
print '输入MV所在网址'
url = raw_input()
if url[0:7] != 'http://':
url = 'http://' + url
print '正在获取名字...'
mvName = getMVName(url)
print mvName
videoId = url[31:]
#print videoId
print '正在获取MV的下载地址'
params = urllib.urlencode({'flex': 'true', 'videoId': videoId})
con = httplib.HTTPConnection("www.yinyuetai.com")
con.request("POST", "/player/get-video-info", params, headers)
r = con.getresponse()
if r.status == 200:
print "Success", "\n"
else:
print "Failed", "\n"
exit()
result = r.read()
con.close()
p=re.compile('http://h.+?.flv')
urls = list(set(p.findall(result)))
print urls
wgetCommand = u'wget ' + urls[0] + u' -O "' + mvName + u'.flv"'
#print wgetCommand
os.system(wgetCommand.encode('utf-8'))
view raw getMV.py hosted with ❤ by GitHub

总结:

其实音悦台也提供了下载功能,但是需要下载一个 Winodows 的客户端,有没有其他的需要我不知道,因为客户端也没用过。

写这种脚本,纯粹是为了满足自己需要。回头想想,觉得这种有用的脚本除了能被人方便的使用以外,还可以告诉程序员:程序无所不能,所有你可以看到的数据都可以获取。

PS:

还搜索到了几个有用的脚本,在这里分享一下:

  • youku-lixian:优酷视频下载的 Python 脚本。
  • youtube-dl:YouTube 视频下载。
  • 易读文库下载器:Windows 平台下载百度文库中文档的工具,话说我也简单分析了一下百度文库的 Flash,有机会也搞一个脚本试试。

完。