Board logo

标题: [网络工具] 批处理整理百度MP3榜单的MP3及LRC文件下载链接地址(图文教程) [打印本页]

作者: namejm    时间: 2011-4-21 18:15     标题: 批处理整理百度MP3榜单的MP3及LRC文件下载链接地址(图文教程)

本文结构如下:

一、缘起:问题的提出
二、试探:徒劳而返
三、峰回路转:芝麻!开门!
四、万事俱备:xml文件里的玄机
五、临阵换将:curl还是wget?
六、下载,我喜欢批量的:如何用迅雷批量下载mp3?
七、收网:从百度MP3榜单批量抓取音乐文件的方案
八、一波三折:查漏补缺,继续完善




一、缘起:问题的提出

  2008年,“音著协”冲冠一怒,与百度音乐对薄公堂。一夜之间,mp3文件的直接下载链接从百度音乐中销声匿迹。

  3年后,在CCF论坛上,有网友问我:能做个抓取百度MP3的批处理么?心中没底,但又感觉并非不可能实现,于是,我审慎地答曰:我试试。


二、试探:徒劳而返

  依稀记得,百度音乐是mp3的集散地,里面宝贝无数。找到里面的“歌曲top500”,对着网页点右键,“使用迅雷下载全部链接”,弹出“选择要下载的URL”对话框,我的心就咯噔了一下。再拉拉右边的下拉条,一条条URL流水般滑过,始终没见到期待中的mp3图标。想到“音著协”与百度音乐的官司,我心里一阵黯然:看来,是不能直接用迅雷来批量下载百度音乐中的MP3文件了——别了,我的MP3饕餮大餐。

  无聊中,手贱,点了某mp3的试听链接,新开了个网页,出来了一个内嵌的播放器,缓冲一阵之后,跳出了一个网页链接,音乐声随之欢快地响起,不由眼前一亮:不就是跳转了一下么?嘿嘿,我可抓住你了!鼠标右键点开“查看源文件”,用网页中内嵌播放器显示的mp3网址一通搜索,竟然踪影全无,我靠,难道还有一层跳转?仔细一看源代码,竟然调用.js无数,吐血数升。

  一连串的打击,让我从失望中看到希望,又从希望中走向绝望,这反倒激起了我的无穷斗志:看不懂html,可我楞是在记事本里折腾了几十分钟;搞不懂iframe,却阻碍不了我动用世界之窗浏览器中查看网页元素的脚步;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文件来分析一下。以黄小琥演唱的“没那么简单”为例:

<?xml version="1.0" encoding="gb2312" ?><result><count>5</count><url><encode>http://zhangmenshiting.baidu.com/data/music/1216653/VndpWXdoXHliV3htWm5pXXJlWHlpW3lxVmprWXptXHl2V2tkWntsXWl2WG1qZKSoZHGrl6SanHVplWtka5lrb5eVbGVsm2-bZ2Jla26cbWhlamRlbm5rbTE$</encode><decode>%E6%B2%A1%E9%82%A3%E4%B9%88%E7%AE%80%E5%8D%95.mp3?xcode=8c806c47fc917e8c60279f6048119845</decode><type>8</type><lrcid>874703</lrcid><flag>0</flag></url><url><encode>http://joy.online.sh.cn/joys/gb/images/site1/20100402/YWJlaWZnbZqTlpeVZZponpKUaGdlbjc$.mp3</encode><decode>0025116bbdda0d1fab5308.mp3</decode><type>1</type><lrcid>874703</lrcid><flag>0</flag></url><url><encode>http://www.aaron.cn/mp3/npecYZ-fmKaVk6E0.mp3</encode><decode>mei-jiandan.mp3</decode><type>1</type><lrcid>874703</lrcid><flag>0</flag></url><url><encode>http://www.jjlxs.com/nqCgnpk2.mp3</encode><decode>mnmjd.mp3</decode><type>1</type><lrcid>874703</lrcid><flag>0</flag></url><url><encode>http://117.34.78.14/bbmedia.qq.com/musictop/new/YmRpZWlmam9mZzM$.wma</encode><decode>1261403755.wma</decode><type>3</type><lrcid>874703</lrcid><flag>0</flag></url><p2p><hash>09e3de9c46e05dca4723e95eb1cc774744c73497</hash></p2p></result>


  上面的内容只有一行,在此只分析和本次目的关系密切的几个标签:<count>5</count>表示获取到5条下载地址,<url>和</url>之间是具体的下载链接,这个链接被分成了两部分:<encode>和</encode>之间的字符串表示mp3文件的网络目录,但你千万别被这一行上带.mp3结尾的字符串所迷惑,以为那就是真实的下载链接——你要知道,百度也不是吃素的,哪能让别人这么容易就抓住了狐狸尾巴?如果你真以为那就是真实的下载链接,那你就中计了。实际上,不管这个字符串最后一个"/"之后的字符串有多长,它们有多么的像一个完整的url地址,你也不能轻易相信那就是完整的、真实的下载链接,那只不过是百度耍的一个障眼法而已,骗骗小白可以,想蒙我,哼哼,没那么容易:把这个字符串最后一个"/"之后的字符串去掉,剩下的那串字符不就是mp3的网络目录么?真正的mp3文件名,是在紧跟其后的<decode>和</decode>之间的那一串字符——即使它们有如一串乱码,不知所云,甚至它们根本就不以.mp3结尾,但你得坚定一条信念,那就是:<decode>和</decode>之间的那串字符真正代表了mp3文件名。把网络目录和mp3文件名合并起来,就是这个mp3文件在网络上的真实下载地址了。比如:http://www.aaron.cn/mp3/mei-jiandan.mp3。<type>和</type>之间的数字,表示音乐文件的类型,有文章分析说,0表示mp3文件,1表示wma文件……从本人浮光掠影的分析结果来看,这些结论已经时过境迁了,唯一不变的就是:这些数字所表示的含义是在不断变化的,可以不用管它们。<lrcid>和</lrcid>之间的数字,表示该歌曲的歌词文件的网络地址信息,规则是:假设这个数为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网页,<a href="……">中填入真实的下载地址,<a>……</a>之间插入文件名,比如“<a href="http://www.aaron.cn/mp3/mei-jiandan.mp3">没那么简单_黄小琥.mp3</a>”。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文件中去,在<a href="……">中写入下载地址,在<a>和</a>之间写入真实的歌曲名;
  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、首先解析<count>和</count>之间的数字,若为0,则把该xml文件对应的歌曲名及歌手名写入下载失败列表中;如果不为0,往下走;
  2、检测第一个url,如果不是来自http://zhangmenshiting.baidu.com,则提取出来,放入批量下载列表中,写入html文件;如果来自那个网站,往下走;
  3、继续解析下一个url,处理步骤如前一条,直至检测到第一个有效的url地址,或者是最后一条url;
  4、分别把有效的url和无效的url写入不同的文件中备查;
  5、考虑到网友们对软件的使用水平有高有低,在html文件中写入提示信息,告知批量下载mp3文件的方法。

  经过本人呕心沥血的测试,再加上孜孜不倦地码字,各位想必已经大致弄懂了用批处理来整理百度MP3上歌曲排行榜的批量下载链接地址的方法了吧?若是如此,本人当可偃旗息鼓了。
作者: namejm    时间: 2011-4-21 18:15

本帖最后由 namejm 于 2011-4-30 21:01 编辑

奉上代码:
注意:
  需要两个工具的配合:
  1、迅雷5.9之前的版本,用于批量下载MP3文件及按注释内容重命名MP3文件;
  2、命令行工具:wget.exe,用于自动获取百度MP3的网络数据并加以处理
wget.exe官方下载地址:http://sourceforge.net/projects/getgnuwin32/files/
wget.exe在本论坛中的下载地址:http://bbs.bathome.net/thread-1114-1-1.html
  1. @echo off
  2. :: 功能:
  3. :: 整理百度MP3歌曲排行榜中除了“中文金曲”和“中国民乐”之外所有榜单的分类下载链接
  4. :: 对MP3文件:整理出供迅雷5等软件批量下载的、有效的mp3文件地址,并统计该榜单下mp3文件的总数、有效下载链接的总数;提供备用的mp3文件下载链接;列出下载链接可能已经失效的mp3文件;
  5. :: 对LRC文件:整理出供迅雷5等软件批量下载的、有效的lrc文件地址,并统计该榜单下lrc文件的总数、有效下载链接的总数;同时下载百度服务器上存在的lrc文件;列出下载链接可能已经失效的lrc文件;
  6. :: 需要配合 榜单分类.ini使用
  7. :: 需要用到命令行工具 wget.exe
  8. :Main
  9. cls
  10. title 百度MP3歌曲排行榜下载链接整理器
  11. echo.&echo.
  12. echo 选择每个项目前的数字序号
  13. echo 可以整理该类别下所有MP3的有效下载链接
  14. echo 并可以下载这些MP3对应的歌词LRC文件
  15. echo 可以多选,但是必须以空格分隔
  16. echo 多选时不用考虑先后次序
  17. echo 例如选择代码时填写 5 1 8
  18. echo 会依次下载“影视金曲”,“新歌TOP100”和“流金岁月”
  19. echo 0与其他选项组合时会造成重复下载
  20. echo.
  21. echo ==========================================================
  22. echo.
  23. setlocal enabledelayedexpansion
  24. set num=0
  25. for /f "tokens=1-3" %%i in (榜单分类.ini) do (
  26.     set /a num+=1
  27.     set /a mod=!num!%%2
  28.     set /p= %%i.%%j <nul
  29.     if !mod! equ 0 echo.&echo.
  30. )
  31. echo.
  32. set /p= 0.前面的所有类别<nul
  33. echo.
  34. echo ==========================================================
  35. echo.
  36. endlocal
  37. set choice=
  38. set /p choice= 请输入选择代码(0/1/2/3/4/5/6/7/8/9):
  39. cls
  40. if not defined choice goto Main
  41. for %%i in (%choice%) do (
  42.     if not "%%i"=="0" (
  43.         for /f "tokens=1-3" %%j in (榜单分类.ini) do (
  44.             if "%%i"=="%%j" (
  45.                 call :Neaten "%%k" "%%l"
  46.                 call :end "%%k"
  47.             )
  48.         )
  49.     )else (
  50.         for /f "tokens=1-3" %%j in (榜单分类.ini) do (
  51.             call :Neaten "%%k" "%%l"
  52.             call :end "%%k"
  53.         )
  54.     )
  55. )
  56. call :end
  57. pause
  58. goto Main
  59. :Neaten
  60. setlocal enabledelayedexpansion
  61. md "%~1\xml" 2>nul
  62. wget -O "%~1\%~nx2" "%~2"
  63. :: 功能:从分类排行榜首页提取出歌曲序号、歌曲名和歌手名,并取回包含真实下载链接的xml文件
  64. :: 歌曲排行随时在变动,清空以前保存的xml文件,以保证不下载过期链接
  65. :: xml文件的下载地址是:http://box.zhangmen.baidu.com/x?op=12&count=1&title=歌曲名$$歌手名$$$
  66. del /a /f /q "%1\xml\*.xml" 2>nul
  67. set num=0
  68. for /f "delims==" %%i in ('set name 2^>nul') do set "%%i="
  69. for /f "delims=" %%i in ('findstr /i "td.class=\"td[b-d]\"" "%~1\%~nx2"') do (
  70.     for /f "tokens=*" %%j in ("%%i") do (
  71.         set /a num+=1
  72.         for /f "delims=<> tokens=3" %%k in ("%%j") do (
  73.             set "name!num!=%%k"
  74.             if !num! equ 2 (
  75.                 if "!name2:~-3!"=="..." (
  76.                     for /f "tokens=4 delims='" %%l in ("%%j") do set "name2=%%l"
  77.                 )
  78.             )
  79.             if !num! equ 3 (
  80.                 if "!name3:~-3!"=="..." (
  81.                     for /f "tokens=2 delims='" %%l in ("%%j") do set "name3=%%l"
  82.                 )
  83.                 set name1=00!name1!
  84.                 set name1=!name1:~-3!
  85.                 if "!name3!"=="/a" set "name3="
  86.                 title 正在下载 %~1 分类下 "!name1!_!name2!_!name3!.mp3" 的xml数据
  87.                 wget -nv -N -O "%~1\xml\!name1!_!name2!_!name3!.xml" "http://box.zhangmen.baidu.com/x?op=12&count=1&title=!name2!$$!name3!$$$"
  88.                 set num=0
  89.             )
  90.         )
  91.     )
  92. )
  93. endlocal
  94. for /f "delims=" %%i in ('findstr /i "td.class=\"tdb\"" "%~1\%~nx2"') do set "str=%%i"
  95. for /f "tokens=*" %%i in ("%str%") do (
  96.     for /f "delims=<> tokens=3" %%j in ("%%i") do set SongNum=%%j
  97. )
  98. :: 功能:整理有效的下载列表,下载对应的歌词文件,列出下载链接已经失效的mp3文件
  99. cls
  100. title 整理%~1的下载链接列表并下载对应的歌词文件
  101. for %%i in (%~1\%~nx2) do set ModifiedTime=%%~ti
  102. for %%i in (MP3 LRC) do (
  103.     (
  104.     echo ^<html^>
  105.     echo ^<title^>百度MP3歌曲排行:%~1^<^/title^>
  106.     echo ^<style type="text/css"^>
  107.     echo ^<!--
  108.     echo a:link { text-decoration: none;color: blue}
  109.     echo a:active { text-decoration:blink}
  110.     echo a:hover { text-decoration:underline;color: red}
  111.     echo a:visited { text-decoration: none;color: green}
  112.     echo --^>
  113.     echo ^<^/style^>
  114.     echo ^<body^>
  115.     echo ^<b^>“百度MP3歌曲排行:%~1”列表更新时间:%ModifiedTime%^<^/b^>^<br^>
  116.     echo ^<font color="red"^>^<b^>注意:以下内容并非“%~1”的全部,仅列出了有效的%%i下载链接^<^/b^>^<^/font^>^<br^>
  117.     if /i "%%i"=="mp3" (
  118.         echo ^<font color="red"^>^<b^>   当本页面中的某些mp3文件下载失败时,请到“%~1mp3备用下载链接.html”中选择相应的备用地址进行下载^<^/b^>^<^/font^>^<br^>
  119.         echo ^<font color="red"^>^<b^>   下载链接有可能失效的mp3文件列表请查看“下载链接可能已经失效的mp3列表.txt”^<^/b^>^<^/font^>
  120.     )
  121.     echo ^<p^>
  122.     echo 批量下载本页面列出的%%i文件的方法(以迅雷5为例,迅雷7不适用):^<br^>
  123.     echo   若您已经安装迅雷,请在本页面点右键,选择“使用迅雷下载全部链接”;^<br^>
  124.     echo   在弹出的“选择要下载的URL”窗口中,勾选“全选”,然后确定^<br^>
  125.     echo   在接下来的“建立新的下载任务”窗口中,“另存名称”选项后点最右侧的倒三角形符号^<br^>
  126.     echo   选择“注释命名”,确定^<br^>
  127.     echo   这样设置之后,下载回来的%%i文件将会以“序号_歌曲名_歌手名.%%i”的格式命名^<br^>
  128.     echo   FlashGet里的操作可以参考以上步骤^<br^>
  129.     echo ====================================================================================^<p^>
  130.     )>%~1\%~1%%i下载链接.html
  131. )
  132. (
  133. echo ^<html^>
  134. echo ^<title^>百度MP3歌曲排行:%~1^<^/title^>
  135. echo ^<style type="text/css"^>
  136. echo ^<!--
  137. echo a:link { text-decoration: none;color: blue}
  138. echo a:active { text-decoration:blink}
  139. echo a:hover { text-decoration:underline;color: red}
  140. echo a:visited { text-decoration: none;color: green}
  141. echo --^>
  142. echo ^<^/style^>
  143. echo ^<body^>
  144. echo ^<b^>“百度MP3歌曲排行:%~1”列表更新时间:%ModifiedTime%^<^/b^>^<br^>
  145. echo ^<font color="red"^>^<b^>注意:以下内容是“%~1”的备用下载地址,仅列出了有效的MP3下载链接^<^/b^>^<^/font^>^<br^>
  146. echo ^<font color="red"^>^<b^>   当“%~1MP3下载链接.html”中某些MP3文件下载失败时,请到本页面选择相应的备用地址进行下载^<^/b^>^<^/font^>^<br^>
  147. echo ^<font color="red"^>^<b^>   请手工选择文件进行单个的下载,若选择批量下载的方式,则会导致同一文件多次下载,并会保存为多个副本^<^/b^>^<^/font^>^<br^>
  148. echo ^<font color="red"^>^<b^>   下载链接有可能失效的MP3文件列表请查看“下载链接可能已经失效的MP3列表.txt”^<^/b^>^<^/font^>^<p^>
  149. echo ====================================================================================^<p^>
  150. )>%~1\%~1MP3备用下载链接.html
  151. (
  152. echo 以下内容为 %ModifiedTime% 更新的“百度MP3歌曲排行:%~1”中下载链接有可能已经失效的mp3文件列表
  153. echo 在本列表中的保存格式为:序号_歌曲名_歌手名.mp3
  154. echo 若您想下载它们,请以相应的关键词在百度MP3网页中搜索有效的下载链接
  155. echo.
  156. )>"%~1\下载链接可能已经失效的mp3列表.txt"
  157. md "%~1\Lrc" 2>nul
  158. (
  159. echo 以下内容为 %ModifiedTime% 更新的“百度MP3歌曲排行:%~1”中未找到下载链接的歌词文件列表
  160. echo 在本列表中的保存格式为:序号_歌曲名.lrc
  161. echo 若您想下载它们,请以相应的关键词在百度MP3网页中搜索有效的下载链接
  162. echo.
  163. )>"%~1\未找下载地址的歌词文件列表.txt"
  164. setlocal enabledelayedexpansion
  165. for /f "delims==" %%i in ('set Url 2^>nul') do set "%%i="
  166. set UrlUseableNum_MP3=0
  167. set UrlUseableNum_URC=0
  168. for %%i in (%~1\xml\*.xml) do (
  169.     for /f "usebackq delims=" %%j in ("%%i") do (
  170.         set "str=%%j"
  171.         set "str=!str:"=!"
  172.         set RunTimes=0
  173.         call :GetUrl %1 Count
  174.         set "UrlUseable="
  175.         set "UrlUseableFirst="
  176.         if !Url_Count! gtr 0 (
  177.             call :GetUrl %1 Encode
  178.             call :GetUrl %1 Decode
  179.             call :GetUrl %1 Lrcid
  180.             call :DownLrc %1 "%%~ni"
  181.             call :GetMp3DownList %1 "%%~ni"
  182.             echo.
  183.         ) else (
  184.             echo %%~ni.mp3>>"%~1\下载链接可能已经失效的mp3列表.txt"
  185.             echo %%~ni.lrc>>"%~1\未找下载地址的歌词文件列表.txt"
  186.         )
  187.     )
  188. )
  189. for %%i in (MP3 LRC) do (
  190.     (
  191.     echo ^<p^>
  192.     echo %~1 下的歌曲共 ^<b^>%SongNum%^<^/b^> 首,有效的%%i下载链接共 ^<b^>!UrlUseableNum_%%i!^<^/b^> 条
  193.     echo ^<^/body^>
  194.     echo ^<^/html^>
  195.     )>>%~1\%~1%%i下载链接.html
  196. )
  197. (
  198. echo ^<^/body^>
  199. echo ^<^/html^>
  200. )>>%~1\%~1mp3备用下载链接.html
  201. endlocal
  202. goto :eof
  203. :GetMp3DownList
  204. :: 功能:获取Mp3的下载链接列表,并下载相应的歌词文件
  205. :: 对当前路径的字符有特殊要求,不能含有\http:\,因为用到了 %%~pi
  206. set /a RunTimes+=1
  207. if %RunTimes% gtr %Url_Count% (
  208.     if not defined UrlUseable (
  209.         echo %~2.mp3>>"%~1\下载链接可能已经失效的mp3列表.txt"
  210.     )
  211.     goto :eof
  212. )
  213. for /f "delims=" %%i in ("%Url_Decode%") do set type=%%~xi
  214. for %%i in (.mp3 .wma) do (
  215.     if /i "%type%"=="%%i" set UrlUseable=true
  216. )
  217. if not defined UrlUseable (
  218.     call :GetUrl %1 Encode
  219.     call :GetUrl %1 Decode
  220.     goto GetMp3DownList
  221. )
  222. for /f "delims=" %%i in ("%Url_Encode%") do set "Url_head=%%~pi"
  223. set "Url_head=%Url_head:*\http:\=%"
  224. set "Url_mp3=%Url_head%%Url_Decode%"
  225. set "Url_mp3=%Url_mp3:\=/%"
  226. if not defined UrlUseableFirst (
  227.     set /a UrlUseableNum_MP3+=1
  228.     (echo ^<a href="http://%Url_mp3%"^>%~2.mp3^<^/a^>^<br^>)>>%~1\%~1mp3下载链接.html
  229.     (echo ^<p^>)>>%~1\%~1mp3备用下载链接.html
  230. ) else (
  231.     (echo ^<a href="http://%Url_mp3%"^>%~2.mp3^<^/a^>^<br^>)>>%~1\%~1mp3备用下载链接.html
  232. )
  233. set UrlUseableFirst=no
  234. call :GetUrl %1 Encode
  235. call :GetUrl %1 Decode
  236. goto GetMp3DownList
  237. :DownLrc
  238. :: 功能:下载歌词文件
  239. if %Url_Lrcid% neq 0 (
  240.     set /a Url_lrc=!Url_Lrcid!/100
  241.     set Url_lrc=!Url_lrc!/!Url_Lrcid!.lrc
  242.     set Url_lrc=http://box.zhangmen.baidu.com/bdlrc/!Url_lrc!
  243.     (echo ^<a href="!Url_lrc!"^>%~2.lrc^<^/a^>^<br^>)>>%~1\%~1LRC下载链接.html
  244.     wget -nv -N -O "%~1\lrc\%~2.lrc" !Url_lrc!
  245.     set /a UrlUseableNum_LRC+=1
  246. ) else echo %~2.lrc>>"%~1\未找下载地址的歌词文件列表.txt"
  247. goto :eof
  248. :GetUrl
  249. :: 提取<……>和</……>标记对之间的字符串
  250. set "str=!str:*<%2>=!"
  251. for /f "delims=< tokens=1*" %%i in ("%str%") do (
  252.     set "Url_%2=%%i"
  253.     set "str=%%j"
  254. )
  255. goto :eof
  256. :end
  257. title %~1整理完毕
  258. cls
  259. echo.&echo.
  260. echo %~1整理完毕
  261. echo.
  262. goto :eof
复制代码
榜单分类.ini的内容:
  1. ;以分号打头的行为注释内容
  2. ;配置文件的格式内容为:编号 分类名称 在百度MP3榜单歌曲排行上对应的首页,三个字段以空格分隔,不能夹带其他字符
  3. ;这些百度MP3榜单首页的列表中,必须有歌曲序号、歌曲名及歌手名这三个字段,歌手名可以为空,即网页源文件代码中必须含有“td class="tdb"”、“td class="tdc"”和td class="tdd"这三行内容
  4. ;“中文金曲”、“中国民乐”因不满足上述条件而无法正确提取,需单独编写代码
  5. ;百度MP3榜单首页:http://list.mp3.baidu.com/index.html
  6. 1 新歌TOP100 http://list.mp3.baidu.com/top/top100.html
  7. 2 歌曲TOP500 http://list.mp3.baidu.com/top/top500.html
  8. 3 日韩流行风 http://list.mp3.baidu.com/top/rihan.html
  9. 4 欧美金曲 http://list.mp3.baidu.com/top/oumei.html
  10. 5 影视金曲 http://list.mp3.baidu.com/top/movie.html
  11. 6 热门对唱 http://list.mp3.baidu.com/top/duichang.html
  12. 7 摇滚歌曲榜 http://list.mp3.baidu.com/top/yaogun.html
  13. 8 流金岁月 http://list.mp3.baidu.com/top/junlvminge.html
复制代码

作者: namejm    时间: 2011-4-21 18:21

放心不下,再附赠图片数张,以加深理解:
作者: batman    时间: 2011-4-21 18:53

惊世之作,值得研究,值得学习。。。
作者: cjiabing    时间: 2011-4-21 18:55

晕,老大真能折腾!~
不过让我终于知道了,为什么我每次下载MP3的时候,都是zhangmenshiting打头的。!~
既然老大能找到其中奥妙,证明老大神功非凡,百度也只能唬唬群众。以我在百度呆的这么多年经验来看,百度也是个弱肉强食的家伙,兄最好将此文提高阅读级别,防止百度登门,好让兄弟们慢慢享受此等优待!~
正好我在写那个batmplayer播放器,顺便以此搞一个在线试听的……哈哈哈……
作者: cjiabing    时间: 2011-4-21 19:19

namejm你太好了,我最近都在找一个在线听歌的方法,你这个东东太令人兴奋了!~
作者: Hello123World    时间: 2011-4-21 20:55

我对你的敬仰有如滔滔江水……
作者: wankoilz    时间: 2011-4-22 11:10

又一个实用工具。解说很到位啊,像看小说一样,佩服,支持!
作者: plp626    时间: 2011-4-22 16:32

看帖收获:
===============================================
以“邓丽君”的“月亮代表我的心”为例,手动方法,体验代码下载流程
1,获得存放MP3及其对应歌词文件的url地址:

   浏览器下输入:
   http://box.zhangmen.baidu.com/x?op=12&count=1&title=月亮代表我的心$$邓丽君$$$$
    (试了下【歌手名】省略后得到的xml信息仍然包含有效链接地址。)

2,提取歌曲的url地址

   在浏览器地址栏打开该url地址后,看到5个被选url地址,每个url地址以如下格式给出:  
   <encode>http://路径/文件名1.mp3</encode>
    <decode>文件名2.mp3</decode>
    我们用文件名2.MP3替换掉 “http://路径/文件名1.mp3”里的文件名1.mp3得到
   http://路径/文件名2.mp3

    在这个例子中我们选择第四个url地址,替换后就是得到了:
    http://www.dlfsy.cn/jisi/jsMusic/月亮代表我的心.mp3
    粘贴它到浏览器地址回车,成功弹出另存为对话框,并保存到桌面成功。

3、再手动下载lrc歌词文件:

   标签<lrcid> <lrcid>对应的数字就是lrc的文件名,而lrc文件路径由两部分组成:
   前部分固定的http://box.zhangmen.baidu.com/bdlrc
    后面的部分是文件名删去后两位。

   在这儿例子中,文件名为22037,删去后两位得到路径的后部分为220
    我们得到了歌词文件的url地址为:

   http://box.zhangmen.baidu.com/bdlrc/220/22037.lrc
    粘贴它到浏览器地址回车,成功看到歌词。
=============================================
这里面第一条非常受用。也不知是哪位强人发现的这个秘密。
作者: namejm    时间: 2011-4-25 15:04

恐怕那个强人不是别人,正是百度的内部员工,我们可以称之为“临时工”
即要表明自己的服务器上没有保存盗版的mp3,以逃避版权组织的责难
又要让广大网民能从自己的服务器上搜到mp3文件,以换取流量便于打广告
恐怕只能推出几个“临时工”来干这些事情了。




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2