利用百度mp3的搜索结果下载网络音乐

以前看到过网友写的“百度Mp3批量下载程序”,现在自己也研究下一。首先上 http://mp3.baidu.com/搜索几首歌,看看百度网站生成动态页面地址的方式。发现它是有规律的,以下是我的记录:

搜索七里香,所有格式
http://mp3.baidu.com/m?f=ms&tn=baidump3&ct=134217728&lf=&rn=&word=%C6%DF%C0%EF%CF%E3&lm=-1 第一页
http://mp3.baidu.com/m?z=0&cl=3&ct=134217728&sn=&lm=-1&cm=1&sc=1&bu=&rn=30&tn=baidump3&word=%C6%DF%C0%EF%CF%E3&pn=30 第二页
http://mp3.baidu.com/m?z=0&cl=3&ct=134217728&sn=&lm=-1&cm=1&sc=1&bu=&rn=30&tn=baidump3&word=%C6%DF%C0%EF%CF%E3&pn=60 第三页
http://mp3.baidu.com/m?z=0&cl=3&ct=134217728&sn=&lm=-1&cm=1&sc=1&bu=&rn=30&tn=baidump3&word=%C6%DF%C0%EF%CF%E3&pn=90 第四页
http://mp3.baidu.com/m?z=0&cl=3&ct=134217728&sn=&lm=-1&cm=1&sc=1&bu=&rn=30&tn=baidump3&word=%C6%DF%C0%EF%CF%E3&pn=720 最后页 30首


搜索七里香,mp3格式
http://mp3.baidu.com/m?f=ms&tn=baidump3&ct=134217728&lf=&rn=&word=%C6%DF%C0%EF%CF%E3&lm=0 第一页
http://mp3.baidu.com/m?z=0&cl=3&ct=134217728&sn=&lm=0&cm=1&sc=1&bu=&rn=30&tn=baidump3&word=%C6%DF%C0%EF%CF%E3&pn=30 第二页
http://mp3.baidu.com/m?z=0&cl=3&ct=134217728&sn=&lm=0&cm=1&sc=1&bu=&rn=30&tn=baidump3&word=%C6%DF%C0%EF%CF%E3&pn=630 最后页7首

搜索七里香,rm格式
http://mp3.baidu.com/m?f=ms&tn=baidump3&ct=134217728&lf=&rn=&word=%C6%DF%C0%EF%CF%E3&lm=1 第一页
http://mp3.baidu.com/m?z=0&cl=3&ct=134217728&sn=&lm=1&cm=1&sc=1&bu=&rn=30&tn=baidump3&word=%C6%DF%C0%EF%CF%E3&pn=30 最后页,17首

搜索七里香,wma格式
http://mp3.baidu.com/m?f=ms&tn=baidump3&ct=134217728&lf=&rn=&word=%C6%DF%C0%EF%CF%E3&lm=2 第一页
http://mp3.baidu.com/m?z=0&cl=3&ct=134217728&sn=&lm=2&cm=1&sc=1&bu=&rn=30&tn=baidump3&word=%C6%DF%C0%EF%CF%E3&pn=30 第二页
http://mp3.baidu.com/m?z=0&cl=3&ct=134217728&sn=&lm=2&cm=1&sc=1&bu=&rn=30&tn=baidump3&word=%C6%DF%C0%EF%CF%E3&pn=240 最后页 13首

搜索七里香,其它格式
http://mp3.baidu.com/m?f=ms&tn=baidump3&ct=134217728&lf=&rn=&word=%C6%DF%C0%EF%CF%E3&lm=32767 第一页
http://mp3.baidu.com/m?z=0&cl=3&ct=134217728&sn=&lm=32767&cm=1&sc=1&bu=&rn=30&tn=baidump3&word=%C6%DF%C0%EF%CF%E3&pn=30 第二页
http://mp3.baidu.com/m?z=0&cl=3&ct=134217728&sn=&lm=32767&cm=1&sc=1&bu=&rn=30&tn=baidump3&word=%C6%DF%C0%EF%CF%E3&pn=240 最后页 4首

上面的链接中,“%C6%DF%C0%EF%CF%E3”是中文“七里香”的6个字节的十六进制编码,可以用“七里香”代替。稍微观察一下就可以发现,“http://mp3.baidu.com/m?f=ms&tn=baidump3&ct=134217728&lf=&rn=&word=歌曲名&lm=格式”就是搜索歌曲第一个结果页面URL,格式有-1(所有格式),0(mp3格式),1(rm格式),2(wma格式),32767(其它格式)5种。我没有把歌词搜索,视频搜索,铃声搜索包括在内,他们跟歌曲搜索的差异太大了。“http://mp3.baidu.com/m?z=0&cl=3&ct=134217728&sn=&lm=格式&cm=1&sc=1&bu=&rn=30&tn=baidump3&word=歌曲名&pn=起始数量N”是搜索第N/30+1页,格式意义同搜索第一页的情况。
   对照网页查看一下其源码,可以发现搜索结果页面中的每首歌曲是这样的形式的存在的

<tr>
<td class=tdn>1</td>
<td class=d><a href="http://202.108.23.172/m?ct=134217728&tn=baidusg,借口 &word=mp3,http://ddos.8833168.cn/wmp3/周杰伦/7hryDjU$.mp3,,[%C6%DF%C0%EF%CF%E3]&si=%BD%E8%BF%DA;;%D6%DC%BD%DC%C2%D7;;3708;;3708&lm=16777216" title="请点击左键!来源网址: http://ddos.8833168.cn/   请参照百度权利声明使用" οnclick="return ow(event,this)" target="_blank">借口 </a></td>
<td><a href="http://mp3.baidu.com/singerlist/%D6%DC%BD%DC%C2%D7.html" target="_blank">周杰伦</a>&nbsp;<a href="http://mp3.baidu.com/singerlist/.html" target="_blank"></a>&nbsp;<a href="http://mp3.baidu.com/singerlist/.html" target="_blank"></a>&nbsp;</td>
<td class=al><a href="http://mp3.baidu.com/albumlist/%D6%DC%BD%DC%C2%D7;;;;;;%C6%DF%C0%EF%CF%E3.html" target="_blank"><font style=color:#e10900>七里香</font></a>&nbsp;</td>
<td><a href="http://box.zhangmen.baidu.com/m?gate=1&ct=134217728&tn=baidumt,借口 &word=mp3,http://ddos.8833168.cn/wmp3/周杰伦/7hryDjU$.mp3,,[%C6%DF%C0%EF%CF%E3]&si=%BD%E8%BF%DA;;%D6%DC%BD%DC%C2%D7;;3708;;3708&lm=16777216" οnclick="return ot(event,this,'3708')">试听</a>&nbsp;</td>
<td><a href="http://mp3.baidu.com/m?tn=baidump3lyric&word=%D6%DC%BD%DC%C2%D7+%BD%E8%BF%DA&ct=150994944&lm=-1&lf=3" target="_blank">歌词</a>&nbsp;</td>
<td> <a name="ls" href="http://mp3.baidu.com/tr?url=http://ad.cn.doubleclick.net/clk;140266405;20620248;r?http://www.12530.com/main/all/subscribe/index/0/qd001/bd0092/1/0/0/null/--------------------------------------2560.html&sn=1" οnclick="return or(event,this);">铃声</a>&nbsp;</td>
<td>3.9 M</td>
<td>mp3</td>
<td class=spd><img src="http://img.baidu.com/img/mp3/d9.gif%22%3E%3C/td>
</tr>

以下是分析结果:
   
    “<td class=tdn>1</td>”:歌曲的序号,每个下载页都不一样的,从1开始递增。我们分析页面中的歌曲就靠这个字符串了。利用一个循环读出所有歌曲下载页,知道查找“<td class=tdn>N</td>”不到为止。
    “http://202.108.23.172/m?ct=134217728&tn=baidusg,借口 &word=mp3,http://ddos.8833168.cn/wmp3/周杰伦/7hryDjU$.mp3,,[%C6%DF%C0%EF%CF%E3]&si=%BD%E8%BF%DA;;%D6%DC%BD%DC%C2%D7;;3708;;3708&lm=16777216”:这个URL就是带下载链接的页面。
   “target="_blank">借口 </a”:“借口”是歌曲的名字,有时搜索结果会有误,比如我搜索“七里香”就出来“借口”,可能是把“七里香”当专辑名了吧,而“借口”是这张专辑的一首歌。所以可以通过检查这里来确定是否下载。
   “<td>3.9 M</td>”:音乐文件的尺寸,一般来说wma有2M以上,Mp3为4M左右。太小的话歌曲不完整。
     “ <td>mp3</td>”:歌曲的类型。

打开http://202.108.23.172/m?ct=134217728&tn=baidusg,借口 &word=mp3,http://ddos.8833168.cn/wmp3/周杰伦/7hryDjU$.mp3,,[%C6%DF%C0%EF%CF%E3]&si=%BD%E8%BF%DA;;%D6%DC%BD%DC%C2%D7;;3708;;3708&lm=16777216这个页面,查看其源码看到:

<div style="padding:30px 0px 0px 40px;">
歌曲名:<a href="http://ddos.8833168.cn/wmp3/周杰伦/借口.mp3">借口   ...</a><br>
<li class="li" style="margin-top:2px;">请点击此链接:</li>

   傻瓜都知道了“http://ddos.8833168.cn/wmp3/周杰伦/借口.mp3”就是下载地址。左边的“歌曲名”和右边的“请点击此链接”是识别它的最明显方式。

了解这些后,不打开浏览器搜索歌曲就容易做了,只要你懂得如何在自己的程序中获取web页面源码。获取页面源码可以用WebBrowser,也可以用速度更快更轻巧的IdHttp组件(Indy套件的一个成员)。使用TIdHttp获取页面的方法是:

   src:=IdHttpObj.Get('www.163.com');


获取页面之后就是利用分析所得到的特征字符串来查找下载链接了。我很笨,不会列举页面的超链接啊,图片啊,表格啊,按钮啊什么的。我采用的是最原始的办法:字符串处理函数。Pos和Copy就够用了。

下面是我的代码,由于是练习玩。写得很不严谨哈。而且没有注释(我认为上面讲得已经很清楚了)。唯一需要说的是,http://202.108.23.172/m?ct=134217728&tn=baidusg,借口 &word=mp3,http://ddos.8833168.cn/wmp3/周杰伦/7hryDjU$.mp3,,[%C6%DF%C0%EF%CF%E3]&si=%BD%E8%BF%DA;;%D6%DC%BD%DC%C2%D7;;3708;;3708&lm=16777216这种URL中含有2个ASCII码为32的控制字符。这两个字符在“&word=”的前面,我们要把它们换成%20(就是32的十六进制码),否则用IdHttp是抓不到页面的。我只是做了最简单抓下载链接的功能。

unit FrmMainUnt;

interface

uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs, StdCtrls, ExtCtrls, ComCtrls, FileDownLoadThread, UrlMon, IdBaseComponent,
    IdComponent, IdTCPConnection, IdTCPClient,
    IdHTTP,StrUtils;

type
    TMusicType 
=  (mtAll =- 1 ,mtMp3 = 0 ,mtRm = 1 ,mtWma = 2 ,mtOther = 32767 );
    TMusicInfo 
=   record
        Name:string;
        DownUrl:string;
        Size: Real;
    
end ;

    TFrmMain 
=  class( TForm )
        ProgBar: TProgressBar;
        edtFileURL: TLabeledEdit;
        edtFilePath: TLabeledEdit;
        Label1: TLabel;
        btnStart: TButton;
        btnCancel: TButton;
        edtMusicName: TLabeledEdit;
        btnSearch: TButton;
        rgType: TRadioGroup;
        IdHTTP: TIdHTTP;
    lstResult: TListBox;
        
procedure  FormCreate( Sender: TObject );
        
procedure  btnStartClick( Sender: TObject );
        
procedure  DownProgress( Sender: TFileDownLoadThread; Progress, ProgressMax: Cardinal );
        
procedure  DownComplete( Sender: TFileDownLoadThread );
        
procedure  DownFail( Sender: TFileDownLoadThread; Reason: LongInt );
        
procedure  btnCancelClick( Sender: TObject );
        
procedure  FormDestroy( Sender: TObject );
        
procedure  btnSearchClick( Sender: TObject );
        
function  SearchMusic(mName:string;mType:TMusicType):string;
        
procedure  GetMusic(ResultUrl:string);
        
procedure  lstResultClick(Sender: TObject);
    private
        FSearchResult:string;
    public
    
{  Public declarations  }
    
end ;

var
    FrmMain: TFrmMain;
    AThread: TFileDownLoadThread;

implementation

{ $R *.dfm }

const
    ModelURL 
= ' http://mp3.baidu.com/m?f=ms&rn=&tn=baidump3&ct=134217728&word=%s&lm=%d ' ;

procedure  TFrmMain.btnCancelClick( Sender: TObject );
begin
    
if  AThread  <>   nil   then
    
begin
        AThread.Terminate;
        AThread.WaitFor;
        FreeAndNil( AThread );
    
end ;
end ;

procedure  TFrmMain.btnSearchClick( Sender: TObject );
var
    MusicType:TMusicType;
begin
    
if  rgType.ItemIndex < 4   then
        MusicType:
= TMusicType(rgType.ItemIndex - 1 )
    
else
        MusicType:
= mtOther;
    try
        FSearchResult:
= SearchMusic(edtMusicName.Text,MusicType);
        GetMusic(FSearchResult);
    except
        FSearchResult:
= '' ;
        ShowMessage(
' search failed ' );
    
end ;
end ;

procedure  TFrmMain.btnStartClick( Sender: TObject );
var
    SaveFileName: string;
begin
    
if  AThread  =   nil   then
        AThread :
=  TFileDownLoadThread.Create( edtFileURL.Text, edtFilePath.Text, DownProgress, DownComplete, DownFail );
end ;

procedure  TFrmMain.DownComplete( Sender: TFileDownLoadThread );
begin
    ShowMessage( 
' 下载完成 '  );
end ;

procedure  TFrmMain.DownFail( Sender: TFileDownLoadThread; Reason: Integer );
begin
    OutputDebugString( PAnsiChar( Format( 
' Down Fail,Reason:%s ' , [ IntToHex( Reason,  8  ) ] ) ) );
end ;

procedure  UpdateProgressBar( Progress, Max: Cardinal );
begin
    
if  Max  >   0   then
        FrmMain.ProgBar.Position :
=  ( Progress  *  FrmMain.ProgBar.Max )  div  Max;
end ;

procedure  TFrmMain.DownProgress( Sender: TFileDownLoadThread; Progress, ProgressMax: Cardinal );
begin
    UpdateProgressBar( Progress, ProgressMax );
end ;

procedure  TFrmMain.FormCreate( Sender: TObject );
begin
    AThread :
=   nil ;
    rgType.ItemIndex:
=- 1 ;
end ;

procedure  TFrmMain.FormDestroy( Sender: TObject );
begin
    btnCancelClick( 
nil  );
end ;

function  GetMusicDownLoadURL(ADownPage:string):string;
const
    str 
=   ' 歌曲名:<a href=" ' ;
var
    I,J:Integer;
begin
    I:
= Pos(str,ADownPage);
    J:
= PosEx( ' "> ' ,ADownPage,I + Length(str));
    Result:
= Copy(ADownPage,I + Length(str),J - I - Length(Str));
end ;

procedure  TFrmMain.GetMusic(ResultUrl: string);
const
    CharStr 
=   ' <td class=tdn>%d</td> '  ;
    CharStr2 
=   ' href=" ' ;
    CharStr3 
=   ' title="请点击左键!来源网址 ' ;
var
    L,I,J:Integer;
    DownPage:string;
    FirstPart,SecondPart:string;
begin
    lstResult.Clear;
    L:
= 1 ;
    
while  True  do
    
begin
        I:
= Pos( Format(CharStr,[L]),ResultUrl);
        
if  I <= 0   then  Break;
        I:
= I + Length(CharStr);
        I:
= PosEx(CharStr2,ResultUrl,I) + Length(CharStr2);
        J:
= PosEx(CharStr3,ResultUrl,I);
        DownPage:
= Trim(Copy(ResultUrl,I,J - I));
        SetLength(DownPage,Length(DownPage)
- 1 );
        I:
= Pos( ' &word= ' ,DownPage);
        FirstPart:
= Copy(DownPage, 1 ,I - 3 );
        SecondPart:
= Copy(DownPage,I,Length(DownPage) - I + 1 );
        DownPage:
= FirstPart + ' %20%20 ' + SecondPart;
        try
            lstResult.Items.Add(GetMusicDownLoadURL(Self.IdHTTP.Get(DownPage)));
        except
        
end ;
        Inc(L);
    
end ;
    
if  lstResult.Count = 0   then
        ShowMessage(
' 没有找到歌曲! ' );
end ;

procedure  TFrmMain.lstResultClick(Sender: TObject);
begin
    
if  lstResult.ItemIndex <>- 1   then
        edtFileURL.Text:
= lstResult.Items[lstResult.ItemIndex];
end ;

function  TFrmMain.SearchMusic(mName: string; mType: TMusicType): string;
var
    AUrl:string;
begin
   AUrl:
= Format(ModelURL,[mName,Ord(mType)]);
   Result:
= Self.IdHTTP.Get(AUrl);
end ;

end .

转载于:https://www.cnblogs.com/coderush/articles/1171487.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值