PHP吸星大法之吸取QQ歌词
毕业前,在学校做了一个Web2.0分享式的音乐在线播放器,前端使用的是Flash调用WMP播放,操作都是在Flash里面进行的,包括显示歌词。
Flash里面显示Lrc歌词不难,几个正则就搞定了。关键在于,歌词从哪里来?自己精力有限,不可能自己去添加歌词,用户上传量大了那还得了,让用户上传呢?一来增加了用户麻烦,而来用户不一定都有歌词文件,有歌词文件的也是一大堆不太好找。算了,还是自己想办法实现自动歌词吧。
起初想到了千千静听,研究了一下千千个歌词,只是发现他有个搜索歌词的地址,不过是加了验证密码的,网上搜索了一下,找到了相应的算法,照着算法改成PHP的,调试几次后,嘿,貌似大功告成了。
可是没几天,就开始不能显示歌词了。我猜被千千屏蔽了,要不然就是改了算法。
正值那段时间,腾讯也发布了自己的网页版QQ音乐(http://y.qq.com),上去看了看,有歌词显示,于是灵机一动:我能不能拔这上面的歌词呢。于是说做就做。
显示随便点了一首歌,观察调用情况,访问的URL队列里面出现了这个:
http://music.qq.com/miniportal/static/lyric/59/137659.xml
其内容格式为
<?xml version=”1.0″ encoding=”gb2312″ ?><lyric><![CDATA[[ti:我曾用心爱着你]
[ar:潘美辰]
[...]
[04:26.58]我会永远把你留在生命里
]]></lyric>
即lrc歌词的xml格式。
分析URL,不难看出定位这首歌的LRC文件使用了两个数,一个是59,一个是137659。
我们再看看其他几首歌曲的歌词URL
http://music.qq.com/miniportal/static/lyric/7/413307.xml
http://music.qq.com/miniportal/static/lyric/11/417711.xml
http://music.qq.com/miniportal/static/lyric/81/237481.xml
http://music.qq.com/miniportal/static/lyric/51/442851.xml
发现什么规律没有?
很简单,第二个数的后面总是以第一个数结尾的,我们可以猜想,第一个数59可能是分类数,第二个数去掉第一个数后的值为1376可能是存放歌曲的ID。于是得出结论,最后一个数的后两位即为分类数。
也就是说,如果我们要定位获取歌词的话,要先得到这两个数才行。
那么,怎么获取这两个数呢?
请求的URL为http://shopcgi.qqmusic.qq.com/fcgi-bin/shopsearch.fcg?value=你是我心内一首歌&type=qry_song&out=json&page_no=1&page_record_num=10&uin=66458168
返回数据的JSON部分为:
{result:”0″,msg:”",totalnum:”15″,curnum:”10″,search:”ÄãÊÇÎÒĞÄÄÚÒ»Ê׸è”,songlist:[{idx:"1",song_id:"400056",song_name:"ÄãÊÇÎÒĞÄÄÚµÄÒ»Ê׸è",album_name:"¸Ä±ä×Ô¼º",singer_name:"ÍõÁ¦ºê Selina",location:"9",singer_id:"265",album_id:"32295",price:"320"}....省略大部分....
分析:乱码部分不管他,那是歌名之类的,直接转到songlist这里,第一个值处有一个song_id,这就是我们要获得的歌词定位的ID号,同时也获取到了分类号。
于是,我们可以通过猜测得知到“你是我心内一首歌”的歌词地址为http://music.qq.com/miniportal/static/lyric/56/400056.xml,打开这个地址,显示果然是这首歌的歌词。
思路清晰了,下面就改用PHP来实现了。这是主要实现的片段,请笑纳:
//到QQ音乐搜索
$keywords = '稻香';
$surl = "http://shopcgi.qqmusic.qq.com/fcgi-bin/shopsearch.fcg?value=".urlencode(strtolower(str_replace(' ', '+', $keywords)))."&type=qry_song&out=json&page_no=1&page_record_num=5";
$contents = file_get_contents($surl);
$ind = strpos($contents, 'song_id:"'); //找到song_id的位置
$contents = substr($contents, $ind+9); //大概在9个字长度处,不绝对
$end = strpos($contents, '"');
$jid = substr($contents, 0, $end);
if (strlen($jid)>3&&is_numeric($jid)){
$lrcurl = "http://music.qq.com/miniportal/static/lyric/".intval(substr($jid, -2))."/{$jid}.xml";
//下载歌词
$lrccon = @file_get_contents($lrcurl);
if($lrccon==''){
echo mb_convert_encoding("[00:00.00]没有这首歌的歌词”, ‘UTF-8′, ‘GBK’);
exit();
}
$st = strpos($lrccon, “<![CDATA[");
$lrc = substr($lrccon, $st+9);
$en = strpos($lrc, "]]>”);
$lrc = substr($lrc, 0, $en);
echo mb_convert_encoding($lrc, ‘UTF-8′, ‘GBK’);
}else{
echo mb_convert_encoding(“[00:00.00]没有这首歌的歌词”, ‘UTF-8′, ‘GBK’);
}
吸星大法打完收工,继续work!!注意低调,以免腾讯发现了改算法!



欢迎订阅:
最新评论
热评文章
崇拜者
[...] 书接上篇博文讲的《PHP吸星大法之吸取QQ歌词》,为了学习PHP扩展的编写,我把这个用PHP扩展实现,与同学们共同学习。 [...]