本文结构如下:
一、缘起:问题的提出
二、试探:徒劳而返
三、峰回路转:芝麻!开门!
四、万事俱备:xml文件里的玄机
五、临阵换将:curl还是wget?
六、下载,我喜欢批量的:如何用迅雷批量下载mp3?
七、收网:从百度MP3榜单批量抓取音乐文件的方案
八、一波三折:查漏补缺,继续完善
一、缘起:问题的提出
2008年,“音著协”冲冠一怒,与百度音乐对薄公堂。一夜之间,mp3文件的直接下载链接从百度音乐中销声匿迹。
3年后,在CCF论坛上,有网友问我:能做个抓取百度MP3的批处理么?心中没底,但又感觉并非不可能实现,于是,我审慎地答曰:我试试。
二、试探:徒劳而返
依稀记得,百度音乐是mp3的集散地,里面宝贝无数。找到里面的“歌曲top500”,对着网页点右键,“使用迅雷下载全部链接”,弹出“选择要下载
的URL”对话框,我的心就咯噔了一下。再拉拉右边的下拉条,一条条URL流水般滑过,始终没见到期待中的mp3图标。想到“音著协”与百度音乐的官司,
我心里一阵黯然:看来,是不能直接用迅雷来批量下载百度音乐中的MP3文件了——别了,我的MP3饕餮大餐。
无聊中,手贱,点了某mp3的试听链接,新开了个网页,出来了一个内嵌的播放器,缓冲一阵之后,跳出了一个网页链接,音乐声随之欢快地响起,不由眼前
一亮:不就是跳转了一下么?嘿嘿,我可抓住你了!鼠标右键点开“查看源文件”,用网页中内嵌播放器显示的mp3网址一通搜索,竟然踪影全无,**,难道还
有一层跳转?仔细一看源代码,竟然调用.js无数,吐血数升。
一连串的打击,让我从失望中看到希望,又从希望中走向绝望,这反倒激起了我的无穷斗志:看不懂html,可我楞是在记事本里折腾了几十分钟;搞不懂
if
rame,却阻碍不了我动用世界之窗浏览器中查看网页元素的脚步;http协议略知皮毛,我依然不知疲倦地在HttpWatch中抓包……凭我的三脚
猫功夫,我还不信搞不定你!who怕who!无知者最大的优点,就是具有大无畏的精神,以为自己的诚心能感动上天,欲以区区两块RMB博得巨额大奖
500W。而当时的我,竟然试图以一己之力,破解百度的MP3下载加密技术。现在回想起来,那是何等的大无畏啊!
单打独斗是行不通的,再次求助于网络。网上bai之go之,以“百度音乐 真实下载地址”、“百度音乐
地址解密”……等等作为关键词,得到结果无数,大都是点开试听链接之后手工单个提取下载链接的方法,偶有一些高级的,竟是下载js之后分析其运作机制后再
编程提取url的,或者干脆把那些js弄回来调用的。可怜我这习惯于在批处理中横冲直撞之人,是断然无法接受手工提取方案的;偏偏又是js白痴一个,看
js代码看得满天星斗,仍然不得要领。一时泄气无比,奄奄一息虚度时日无数。
三、峰回路转:芝麻!开门!
忽然有一天,记得当时大事不断:一个常去的网站在我猛按F5之后,竟然一整天都停留在404界面上;一老乡哭丧着脸说他工作上一个非常重要的word
文档无意中删除内容被清空了,央求我帮他恢复一下数据;某同事让我重装系统,全新安装之后,才发现居然没有找到随机的驱动盘,而身边竟然无网可用;正在工
地上行走,忽然一脚踩空从1米多高的地方倒栽进坑里,灰头土脸地正拍打着,却发现电脑还在身旁空转,桌上口水成堆,额头上一个大包,这才惊觉此乃南柯一
梦……那是非常特别的一天,屋漏偏逢连夜雨,生活中万分之一小概率的事情全堆在一起,接踵而至。半梦半醒之际,我见证了否极泰来,一件十分重大的事情发生
了,那就是:我找到了打开宝藏之门的钥匙!从此之后,我只要口中念念有词,轻喝一声:芝麻!紧闭的百度音乐之门将轰然洞开。
这一切,源于一个叫百度音乐API的玩意。
你见,或者不见,它就在那里,有增有减;你知,或者不知,它都在等你,不曾离去。表面上,百度声称它的服务器中不存放MP3文件本身,而只是提供了搜
索的链接结果;表面上,在百度MP3中搜索到的音乐文件,是需要层层跳转到某个界面才可以看到真实的下载链接;表面上,那个经常排在所有下载链接中第一个
的http://zhangmenshiting.baidu.com网站下载链接,过了一两个小时再用同一url是无法下载的;表面上,百度搜索到的下载链接来源五花八门……实际上呢?实际上,那个叫http://zhangmenshiting.baidu.com/的
网站经常排在众多下载链接的第一位;实际上,大部分mp3文件的来源其实真的只有那么几个;实际上,那些下载链接真的不在百度的服务器上;实际上,百度真
的已经从服务器上断开了它们的链接……真的,以前辛辛苦苦收集了好几年的mp3文件,已经一夜之间从百度服务器上消失了;真的,百度服务器上是有那么一张
表,表上记录了网上众多mp3的下载链接,只要你愿意搜,总能在这张表上找到它们,可它们真的不在我百度的服务器上啊,你懂的。
实际上,百度音乐是没有API的,因为,它从来就没有出现在我百度的官方网站上;网上流传的那些所谓的“不公开的API”,都是临时工干的。
经过我的反复搜索,我发现那个临时工大约是在2009年10月份干的这件事情(确切时间待考),顺带说一声,是在百度hi上。这个API的真面目是:http://box.zhangmen.baidu.com/x?op=12&count=1&title=
大约在冬季$$齐秦$$$$,“大约在冬季”可以用任意歌曲名替换,“齐秦”可以用对应的歌手名来替换。有了这个API,只需要知道歌曲名和歌手名,或者
只知道歌曲名,就能从百度服务器中取回一个xml文件,在这个xml文件中,含有这首歌曲MP3文件的真实下载地址,并且大部分都提供有多个备用地址。
歌曲名和歌手名上哪里去找?百度MP3网页的那些分类里不是有现成的么?真是环环相扣啊!只要你有办法批量找到歌曲名和歌手名的对应关系,那,找到mp3文件的真实下载链接将是轻而易举的事情!
那我们就开始找歌曲名和歌手名的对应关系吧。
打开百度MP3网页:http://mp3.baidu.com,进“榜单”里瞅瞅:http://list.mp3.baidu.com/index.html,我们的重点在“歌曲排行”。为啥?不解释,跟我来吧。看看“新歌100”:http://list.mp3.baidu.com/top/top100.html,
是不是发现有“1 医生 许嵩”、“2 星辰变
吴克群”……之类的?有木有?是不是一拉就一大堆?有木有?点右键,“查看源文件”,用这些歌曲名或歌手名做关键词,是不是可以搜索到对应的另一半?有木
有?到底有木有?看看“歌曲top500”、“日韩流行风”等等(中文金曲和中国民乐除外),是不是都同一副德行?有木有?有木有?
如果要把“新歌100”中歌曲名和歌手名的对应关系一一找出来,我只需用 wget -O top100.html "http://list.mp3.baidu.com/top/top100.html"
就可以把这个网页文件下载到本地,然后,用 findstr /i "td.class="td[b-d]"" top100.html
把含有歌曲序号、歌曲名和歌手名这些信息的行提取出来,放for中切分一下,剔除多余的信息,仅保留歌曲序号、歌曲名和歌手名,并不是什么困难的事情。然
后再用 wget -O "序号_歌曲名_歌手名.xml" "http://box.zhangmen.baidu.com/x?op=12&count=1&title=歌曲名$$歌手名$$$$",乖乖,不得了了,这些歌曲的下载地址转眼之间都被抓回来了。
四、万事俱备:xml文件里的玄机
我们找一个xml文件来分析一下。以黄小琥演唱的“没那么简单”为例:
上面的内容只有一行,在此只分析和本次目的关系密切的几个标签:5表示获取到5条下载地
址,和之间是具体的下载链接,这个链接被分成了两部分:和<
/encode>之间的字符串表示mp3文件的网络目录,但你千万别被这一行上带.mp3结尾的字符串所迷惑,以为那就是真实的下载链接——你要知
道,百度也不是吃素的,哪能让别人这么容易就抓住了狐狸尾巴?如果你真以为那就是真实的下载链接,那你就中计了。实际上,不管这个字符串最后一个"/"之
后的字符串有多长,它们有多么的像一个完整的url地址,你也不能轻易相信那就是完整的、真实的下载链接,那只不过是百度耍的一个障眼法而已,骗骗小白可
以,想蒙我,哼哼,没那么容易:把这个字符串最后一个"/"之后的字符串去掉,剩下的那串字符不就是mp3的网络目录么?真正的mp3文件名,是在紧跟其
后的和之间的那一串字符——即使它们有如一串乱码,不知所云,甚至它们根本就不以.mp3结
尾,但你得坚定一条信念,那就是:和之间的那串字符真正代表了mp3文件名。把网络目录和
mp3文件名合并起来,就是这个mp3文件在网络上的真实下载地址了。比如:http://www.aaron.cn/mp3/mei-jiandan.mp3。
和之间的数字,表示音乐文件的类型,有文章分析说,0表示mp3文件,1表示wma文件……从本人浮光掠影的分析结果来看,这
些结论已经时过境迁了,唯一不变的就是:这些数字所表示的含义是在不断变化的,可以不用管它们。
和之间的数字,表示该歌曲的歌词文件的网络地址信息,规则是:假设这个数为A,用A除以100,取结果的整数B,拼凑起形
如"http://box.zhangmen.baidu.com/bdlrc/B/A.lrc"的路径,这个路径就是这个歌词文件的下载地址!在这个例子中,874703除以100再取整数部分,得到8747,拼凑起来就得到了“没那么简单”这首歌曲在百度服务器上的下载地址:http://box.zhangmen.baidu.com/bdlrc/8747/874703.lrc。
五、临阵换将:curl还是wget?
最开始,下载网络数据我一直使用的是curl。我对它的偏爱,源于对它的熟悉以及对其他命令行下载工具的陌生,“无它,唯手熟耳”。
用得多了,就开始感到了它的不足:有时候,某个网页明明可以通过IE浏览器看到,但用curl下载回来的时候,竟然少了很多内容;找到了某个文
件,curl下载之,居然纹丝不动。抱着试试看的心态,试用了一下wget,下载精准,速度飞快,完全是另外一个境界,大喜,遂弃curl而改用
wget。
六、下载,我喜欢批量的:如何用迅雷批量下载mp3?
获取单条下载地址,Ctrl+C之后,Ctrl+V手工输入迅雷的下载界面中去,再手工改名,如此这般,周而复始,天呐,百度MP3里的歌曲成千上万,这得下载到猴年马月啊?
有没有什么办法,让迅雷批量下载那些MP3?不仅仅是下载就了事,最好还得在下载的时候,自动重命名mp3文件为含歌曲名+歌手名的格式?要不然,面
对下载回来的一堆以随机的数字+字符命名的mp3文件,我怎么知道谁是谁啊?总不能全部试听一遍之后再重命名吧?想自虐也得找点科技含量高点的方式吧?
以本人多年使用迅雷的经验,批量下载mp3的方式有两个:1、把下载地址保存为.lst文件,一行一条url,不能多也不能少,迅雷之中使用“导入下
载列表”的功能即可;2、构造html网页,嵌入url地址,网页浏览器中点右键,“使用迅雷下载全部链接”,筛选后即可。
整理成.lst文件,可以大幅压缩文件体积,但此法稍显冷僻;整理成html网页,点右键选择更具有直观性,是大众化的操作方式。
到目前为止,仅仅解决了批量下载的方式,自动重命名又该如何处理?
记得在迅雷的早期版本中,是可以在.lst文件中写入注释内容的,在迅雷的下载界面中再配合“以注释命名”的方式,是可以实现批量下载+自动以注释内
容重命名文件的想法的,惜乎记忆模糊,几番折腾下来,仍然不得其法,莫非在新版本中已经不支持在.lst文件中写入注释内容了?一如迅雷升级到7.X版本
之后,就放弃了方便无比的、批量“以注释内容重命名文件”的功能?
CCF发帖求助,无解,但得知迅雷5和FlashGet支持从网页代码中获取文本内容作为重命名文件时的注释内容,无心插柳柳成荫,这真是一个重大的意外收获,为后续的自动重命名铺平了道路。
构造了一个html网页,中填入真实的下载地址,……之间插入文件名,比如“http://www.aaron.cn/mp3/mei-jiandan.mp3">
没那么简单_黄小琥.mp3”。IE中打开html,右键选择“使用迅雷下载全部链接”,调用迅雷5,弹出“选择要下载的URL”界
面,先取消“全选”,再点“筛选”。“扩展选择”中,“站点”之下,选择相应站点,“扩展名”之下,选择.mp3及.wma。一路确定,来到“建立新的下
载任务”界面,选择好存储目录,在“另存名称”之后,点尾部的倒三角形,选择“注释命名”,确定之后,将会把网站上的"mei-jiandan.mp3"
下载回来,并自动重命名为"没那么简单_黄小琥.mp3"。
如果只有一条记录,那就是单文件下载;如果列表中有N条记录,这不就是传说中的批量下载么?转眼之间,就可以把网络上经过整理的经典mp3搬回家,哈哈,这是件何等幸福的事情啊!
题外话:为什么要用迅雷?wget不可以下载mp3么?答曰:wget也可以下载mp3,并且还能实现从头到尾的全程自动化,但网络中有一种令下载狂
们闻之色变叫做的“死链”的东西。批处理仅负责整理下载链接,而把下载mp3文件的重任交给迅雷,是希望借助迅雷强大的智能搜索功能,最大程度地消除死链
的影响,并在中途断开网络的时候,能保存下载进度,实现下一次的断点续传,尤为重要的是,在这个速度为王的时代,我们还希望借助它的吸血特性,保证下载的
高速度。
七、收网:从百度MP3榜单批量抓取音乐文件的方案
事已至此,我已看到彩旗招展,我已听到锣鼓喧天,压轴大戏,已经就位,只等一声令下,就可以登台亮相了。从百度MP3批量抓取音乐文件的方案就此出炉:
1、把百度MP3榜单的分类地址保存到一个配置文件中,一行一个分类,以便批处理读取;
2、wget下载每个分类的html页面,从中获取歌曲名和歌手名的对应列表;
3、把歌曲名和对应的歌手名信息嵌入"http://box.zhangmen.baidu.com/x?op=12&count=1&title=歌名$$歌手名$$$"这个URL中,down回一个含有真实下载链接的xml文件;
4、从xml文件中提取mp3文件的第一个下载地址(为什么同一mp3文件不整理出多个url——一个地址足矣,难道你想一个文件下载多个副本么?),顺手牵羊把对应的lrc地址也整理一下;
5、把mp3文件的下载地址列表整理到html文件中去,在中写入下载地址,在和之间写入真实的歌曲名;
6、剩下的事情,交给迅雷来处理吧,记得文件的命名方式要选择"注释命名";
7、over,您就等着享受吧。
八、一波三折:查漏补缺,继续完善
什么?有些文件下载不回来?迅雷那么牛,居然还有不给力的时候?
查,给我查,一查到底,绝不手软……貌似这话非常熟悉,在哪里听过?
记事本不够用了,EditPlus顶上;批处理太快了,开CMD窗口单步执行;迅雷可能有盗链,会影响问题源头的跟踪,那就开动wget检查……把无法下载的url都汇总一下,看看它们都有哪些共同之处。
2011年3月,携3.15之余威,“文著协”与百度文库对决于网络。初期,百度文库坚称自己仅是一个平台,适用网络避风港原则,拒不承认自己的产品
有侵权行为;后来,在监管部门和舆论的双重压力之下,3月底,百度文库文学作品的数量从280万份锐减至100余份,百度文库声称已经在自己的平台上断开
了涉嫌侵权作品的网络链接。
呵呵,好一个“已经断开了它们的网络链接”!你见,或者不见,它就在那里,增多减少,你懂的。想当初,百度音乐不也是声称自己已经断开了mp3文件在百度音乐网站上的下载地址网络链接了么?
我发现,有个叫http://zhangmenshiting.baidu.com的
网址频繁出现于下载回来的xml文件中,并且往往盘踞在第一位,甚至整个xml文件全是这个网址的链接。很明显,这个网站是百度的,不需要url转码,直
接拼音翻译,连起来就是:爱曲踢踢屁://掌门试听.百度.可摸。百度音乐服务器上没有保存mp3并供网民下载么?鬼才信。不过貌似近期有传言说百度和
“音著协”有了合作,利润分成,在百度服务器上放正版音乐文件,可能也是合作内容的一部分吧。不过,百度没有做得那么肆无忌惮,这个下载链接是有时效性
的,可能是10分钟之后,也可能是一两个小时,当你再次用http://zhangmenshiting.baidu.com上的同一个url地址下载mp3文件的时候,是没法继续下载的,好像这个文件就从来没有在百度的服务器上存在过一样。
当我只提取第1条url、并且第1条url正好是http://zhangmenshiting.baidu.com网站上的地址的时候,有可能无法下载到mp3文件的悲剧就发生了。从http://zhangmenshiting.baidu.com这个网址长期占据大部分下载链接的第一位这个有百度特色的现象来看,这种悲剧不是小概率事件。
举一反三,其他的网站可能也存在类似的情况,甚至会存在文件被移走、删除、网站倒闭等极端情况,毕竟,这就是网络,“水无常势,兵无常形”,一切都在变化之中,唯一不变的就是:网络随时都在发生改变。
“死链”终于还是来了,有百度特色的、没有百度特色的,概莫能外,这个问题必须解决,刻不容缓。
好在下载回来的xml文件中包含的下载链接往往不只一条,表面上看是来自多个网站的。看来百度早就预料到了死链的问题,所以提供了多个备用的下载地址。那我也就不客气了,一一笑纳,也弄一个备用下载链接的网页文件吧,但是,来自http://zhangmenshiting.baidu.com的下载链接是绝对不能再要了。
即使有备用下载链接做保证,“死链”仍然是无法避免的,更有甚者,连http://box.zhangmen.baidu.com都没有收集到——是它不能,还是它故意不给?无从猜测。总之,有些mp3是没法搞定的。那就弄个文件,保存一下无法下载回来的mp3文件列表吧,如果追求完美的话,以后也可以打开这个文件,用里面的关键词在网上手工搜索下载链接。
看来,整理xml文件中的下载链接的时候,还得考虑各种死链问题,整理xml文件的方案还得做如下修改:
1、首先解析和之间的数字,若为0,则把该xml文件对应的歌曲名及歌手名写入下载失败列表中;如果不为0,往下走;
2、检测第一个url,如果不是来自http://zhangmenshiting.baidu.com,则提取出来,放入批量下载列表中,写入html文件;如果来自那个网站,往下走;
3、继续解析下一个url,处理步骤如前一条,直至检测到第一个有效的url地址,或者是最后一条url;
4、分别把有效的url和无效的url写入不同的文件中备查;
5、考虑到网友们对软件的使用水平有高有低,在html文件中写入提示信息,告知批量下载mp3文件的方法。
经过本人呕心沥血的测试,再加上孜孜不倦地码字,各位想必已经大致弄懂了用批处理来整理百度MP3上歌曲排行榜的批量下载链接地址的方法了吧?若是如此,本人当可偃旗息鼓了。