本文 15871 pv

0

php实现百度音乐采集下载

© kekehu / 信息抓取 / 2009.12.20 / 10:30 / 15871PV

简介:支持 歌名+歌手 此方式下载,所以支持百度mp3(新歌TOP100、歌曲TOP500、经典老歌、热门对唱、相声小品荟萃、摇滚歌曲榜)下载。

在网上没找到php cli方式的下载百度mp3的脚本,很奇怪,php挺流行就是cli方式却很少,安全问题,效率问题?个人还是挺喜欢这种方式的。比如批量的图片缩放,合并,用 ImageMagick 比 GD 效率好多了,而且功能也多,但需要安装插件,太麻烦,直接用system调用ImageMagick,方便又灵活,perl ,python 都是这样做的,为什么php不行。

难点:
1、对html页面进行正则分析,获取歌名、歌手、mp3地址。参考preg_match_all。
2、百度mp3地址用js加密了,把它解出来。
原理在shell 方式有详细说明,不再罗嗦,简单说2句:
取加密地址第一位,然后根据这个来生成 search。
取加密地址中:的位置来生成replace。
然后用str_replace(search, replace, encode)来解密,但 str_replace 函数不行,我用了另一种方法,见代码。

说明:
1、根据机器安装了是否安装了ffmpeg,来选择下载。如果没有安装,那么MP3_TYPE就仅仅是mp3,如果安装了,根据需要下载所有类型歌曲。
2、下载的歌曲大小有个选择范围,默认3M-10M,可以根据需要自己调节。
3、下载方式有wget和mytget,因为wget是单线程下载,并不是说不好,如果你有足够耐性而且机器没有安装mytget,就用wget好了。
4、下载的歌曲是按“歌手拼音_歌名拼音.mp3”重命名,另生成asx文件,方便播放。

< ?php
define('BAIDU_URL', 'http://list.mp3.baidu.com/topso/mp3topsong.html?top2');
//for get file
define('GET_TYPE', 'mytget');    //wget or mytget,default wget.
define('GET_TMP', '/tmp');
define('MP3_FOLDER', '/home/xxx/public_html/download/mp3/baidu');
//file type and size(M)
define('MP3_TYPE', 'mp3,wma');
define('MP3_MAX', 10);
define('MP3_MIN', 3);
//for build asx file
define('MP3_URL', 'http://download.xxx.com/mp3/baidu');
define('PLAYLIST_FILE', '/home/xxx/public_html/player/top500.asx');

//begin
include_once('hanzi2pinyin.php');
include_once('jscoding.php');
$stringHtmlContent = file_get_contents(BAIDU_URL);
preg_match_all("#<a\shref=\"(.*?)\"\starget=_blank>(.*?)(\s+)\((.*?)\)#i", $stringHtmlContent, $arrayHtmlContent);
//print_r($arraySongContent);exit();
$intHtmlContent = count($arrayHtmlContent[0]);
for($i=0; $i< $intHtmlContent; $i++)
{
    $stringUrl = trim($arrayHtmlContent[1][$i]);
    $stringTitle = trim(strip_tags($arrayHtmlContent[2][$i]));
    $stringAuthor = strtoupper(trim(strip_tags($arrayHtmlContent[4][$i])));
    echo "($i)$stringTitle($stringAuthor)\n";
    $stringMp3Name = preg_replace('/[^a-z0-9.&_]/', '', hanzi2pinyin(strtolower(str_replace('/', '&', $stringAuthor) . '_' . $stringTitle)) . '.mp3');
    $stringMp3File = MP3_FOLDER . '/' . $stringMp3Name;
    if(!is_file($stringMp3File))
    {
        echo "=    Download...\n";
        getlist($stringUrl, $stringTitle, $stringAuthor, $stringMp3Name);
    }
    if(is_file($stringMp3File))
    {
        //build asx
        $arraySongs[] = array(
            'title' => $stringTitle,
            'author' => $stringAuthor,
            'url' => MP3_URL . '/' . $stringMp3Name,
        );
    }
}
//write asx
echo "Writing asx file...\n";
$stringContent .= "<asx version=\"3.0\">\n";
$stringContent .= "<title>My Favorite Songs</title>\n";
$stringContent .= "<param name=\"allowshuffle\" value=\"yes\"/>\n";
foreach($arraySongs as $arraySong)
{
    $stringContent .= "\t<entry>\n";
    $stringContent .= "\t\t<title>" . iconv('GB2312', 'UTF-8//IGNORE', $arraySong['title']) . "</title>\n";
    $stringContent .= "\t\t<author>" . iconv('GB2312', 'UTF-8//IGNORE', $arraySong['author']) . "</author>\n";
    $stringContent .= "\t\t<ref href=\"" . $arraySong['url'] . "\"/>\n";
    $stringContent .= "\t</entry>\n";
}
$stringContent .= "</asx>\n";
file_put_contents(PLAYLIST_FILE, $stringContent);
echo "Finished...\n";

//print_r($arraySong);

function getlist($url, $title, $author, $name)
{
    $stringHtmlContent = file_get_contents($url);
    preg_match_all("#<td \sclass=d><a \shref=\"(.*?)\"(.*)><font color=\"\#c60a00\">(.*?)</font>(\s+)</a></td>(\s+)<td>(.*?)</td>(\s+)<td \sclass=al>(.*?)</td>(\s+)<td>(.*?)</td>(\s+)<td>(.*?)</td>(\s+)<td>(.*?)</td>(\s+)<td>(.*?)\sM</td>(\s+)<td>(.*?)</td>#i", $stringHtmlContent, $arrayHtmlContent);
//    print_r($arrayHtmlContent);exit();
    $intHtmlContent = count($arrayHtmlContent[0]);
    for($i=0; $i< $intHtmlContent; $i++)
    {
        if(!is_file(MP3_FOLDER . '/' . $name))
        {
            $stringUrl = trim($arrayHtmlContent[1][$i]);
            $stringTitle = trim(strip_tags($arrayHtmlContent[3][$i]));
            $stringAuthor = strtoupper(str_replace(' ', '/', trim(str_replace('&nbsp;', ' ', strip_tags($arrayHtmlContent[6][$i])))));
            $stringSize = trim($arrayHtmlContent[16][$i]);
            $stringType = trim($arrayHtmlContent[18][$i]);
            if(($stringTitle == $title) && ($stringAuthor == $author) && ($stringSize > MP3_MIN) && ($stringSize < MP3_MAX) && (in_array($stringType, split(',' ,MP3_TYPE))))
            {
                echo "==    List($i)[$stringSize M]: ";
                getsong($stringUrl, $name, $stringType);
            }
        }
    }

}

function getsong($url, $name, $type)
{
    $stringHtmlContent = file_get_contents(encodeURI($url));
    preg_match_all('#I="(.*)",J=#i', $stringHtmlContent, $arrayHtmlContent);
    $stringUrl = songdecode(trim($arrayHtmlContent[1][0]));
    echo "$stringUrl\n";
    if($type != 'mp3')
    {
        $stringName = $name . '.' . $type;
    }
    else
    {
        $stringName = $name;
    }
    $stringFileOld = GET_TMP . "/" . $stringName;
    $stringFileNew = MP3_FOLDER . "/" . $name;
    if(GET_TYPE == 'mytget')
    {
        system("mytget -t 10 -c 3 -n 5 -d '" . GET_TMP . "' -f '$stringName' '$stringUrl'");
    }
    else
    {
        system("wget -q -T 10 -t 3 -c '$stringUrl' -O '$stringFileOld'");
//        system("wget -T 60 -t 10 -c '$stringUrl' -O '$stringFileOld'");
    }
    if((is_file($stringFileOld)) && (filesize($stringFileOld) > MP3_MIN*1024*1024) && (filesize($stringFileOld) < MP3_MAX*1024*1024))
    {
        echo "===    Song: $stringName\n\n";
        if($type != 'mp3')
        {
            system("ffmpeg -i '$stringFileOld' '$stringFileNew'");
        }
        else
        {
            system("cp '$stringFileOld' '$stringFileNew'");
        }
    }
    system("unlink '$stringFileOld'");
}

function songdecode($url)
{
    $charHead = substr($url, 0, 1);
    $arraySplit = split($charHead, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789');
    $stringQue = $charHead . $arraySplit[1] . $arraySplit[0];
    if(strpos($url, ':') == 3)
    {//ftp
        $stringKey = 'fghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcde';
    }
    else
    {//http
        $stringKey = 'hijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefg';
    }
    $arrayQue = preg_split('//', $stringQue, -1, PREG_SPLIT_NO_EMPTY);
    $arrayKey = preg_split('//', $stringKey, -1, PREG_SPLIT_NO_EMPTY);
//    return str_replace($arrayQue, $arrayKey, $stringQue); //why error?
    $arrayReplace = array_combine($arrayQue, $arrayKey);
    $arrayUrl = preg_split('//', $url, -1, PREG_SPLIT_NO_EMPTY);
    foreach($arrayUrl as $charUrl)
    {
        if($arrayReplace[$charUrl] == '')
        {
            $stringUrl .= $charUrl;
        }
        else
        {
            $stringUrl .= $arrayReplace[$charUrl];
        }
    }
    return $stringUrl;
}
?>


hanzi2pinyin.php文件下载
hanzi2pinyin.rar (已下载 929 次)
jscoding.php文件下载。

首次运行可适当增加苛刻条件,比如类型是mp3大小在4-6,然后适当放宽条件。多运行几次。

参考:
shell 方式下载参考:http://forum.ubuntu.org.cn/viewtopic.php?f=21&t=160965
perl 方式下载参考:http://hi.baidu.com/ximix/blog/item/7dd00c24d4513e37c995593a.html
python 方式下载参考:http://blog.chinaunix.net/u2/82843/showart_1665292.html
PHP Javascript Ajax – urlencode rawurlencode encodeURI encodeURIComponent urldecode rawurldecode decodeURI decodeURIComponent

此文章转自网络,如有问题请回复。

本文有 0 篇评论

发表你的见解

打开HTML 打开UBB 打开表情 隐藏 记住我
emotemotemotemotemotemotemotemotemotemotemotemotemotemotemotemotemotemotemotemot
emotemotemotemotemot