|
越到重要關(guān)頭的時(shí)候,就越?jīng)]事找事,總是“想做的事”優(yōu)先級(jí)高于正經(jīng)事,唉,沒(méi)救了~
早些時(shí)候,我就在用LongkeyMusic,很方便,可以下載蝦米的精選集,不過(guò)很久都不更新,下的精選集也常常是無(wú)效的,所以改用了 蝦米音樂(lè)河蟹姬,地址解析是不錯(cuò),UI做得也很二次元,就不知道寫這程序的人是怎么想的?一個(gè)好好的程序,下載的歌曲都是以ID號(hào)命名,批量下了一大推,沒(méi)聽過(guò)的都不知道叫啥!
跟上次的思路一樣,想從外部改進(jìn)這個(gè)程序,控制程序句柄,不過(guò)很遺憾,用Spy++查看這個(gè)程序,風(fēng)格也是子窗口嵌入主窗口里的,找不出我要的句柄。沒(méi)辦法了。
在網(wǎng)上搜搜還有沒(méi)有更好的蝦米音樂(lè)獲取辦法,找到一篇日志 蝦米音樂(lè)文件絕對(duì)地址解析 ,按上面試了試,雖有點(diǎn)不一樣,不過(guò)確實(shí)是可以獲取出蝦米音樂(lè)真實(shí)下載地址的,所以就想自己也寫個(gè)程序玩玩。
//*********************************************************************************************//
方法也是參考自:蝦米音樂(lè)文件絕對(duì)地址解析 http://kanoha.org/2011/08/30/xiami-absolute-address/
簡(jiǎn)單原理如下:
以 http://www.xiami.com/song/3632733?spm=a1z1s.6659513.0.0.zzUExi 為例
1、把song替換成widget/xml-single/sid ,在網(wǎng)頁(yè)上打開替換后的地址,得到一個(gè)XML文件;有興趣的,可以試試對(duì) 專輯 album類的捕捉,XML我不會(huì)。。。反正是按圖索驥了
2、可以得到下圖,有很多信息,最后一個(gè)框就是下載地址的密文了。
密文如下:
9hFlc%2521%e213f45lt%eo2FE713y672e3Elt2.mF3532F%938e2-pFx%72%3_a314373%%mi2762_luD184c2535aF4%F1.t4%3%-%EA.m44537mhe5b515-%fi43E68p_3E5E3En2i.3%%363k73eb9%u
3、按上面日志說(shuō)的,第一個(gè)字符是9,可以看成是凱撒方陣的列數(shù),按凱撒方陣來(lái)排列,由于字符串中包含有音樂(lè)文件的下載地址,很特殊,所以簡(jiǎn)單一點(diǎn),一般找出http這幾個(gè)字母也就得出了凱撒方陣
hFlc%2521%e213f45l
t%eo2FE713y672e3El
t2.mF3532F%938e2-
pFx%72%3_a314373%
%mi2762_luD184c25
35aF4%F1.t4%3%-%E
A.m44537mhe5b515-
%fi43E68p_3E5E3En
2i.3%%363k73eb9%u
4、豎著讀,得到
http%3A%2F%2Fm5.file.xiami.com%2F443%2F77443%2F326%5E%5E5%2F3632733_1786112_l.mp3%3Fauth_key%3D4e3726911%5E3173483b5e32834%5Ebfee7c-13943232%5E%5E-%5E-null
5、有木有感覺(jué)了?經(jīng)過(guò)在線網(wǎng)頁(yè)的URL解碼,得到
http://m5.file.xiami.com/443/77443/326^^5/3632733_1786112_l.mp3?auth_key=4e3726911^3173483b5e32834^bfee7c-13943232^^-^-null
6、替換^為0,即為真實(shí)下載地址了
?auth_key=4e372691103173483b5e328340bfee7c-1394323200-0-null
其中 3632733_1786112_l.mp3 即為默認(rèn)文件名
//*********************************************************************************************//
//*********************************************************************************************//
有了上面的方法,那就差一個(gè)具體的實(shí)施了,最簡(jiǎn)單的辦法,可以用網(wǎng)頁(yè)腳本語(yǔ)言,Java,HTML,css,Python.......
我不會(huì),就用delphi了
界面布局: 顯示效果:
感覺(jué)UI做得越來(lái)越好了。
//*********************************************************************************************//
//*********************************************************************************************//
下面是部分關(guān)鍵代碼:
//************************ 點(diǎn)擊解析并保存按鈕 *****************************************//
procedure TForm1.resolveBtnClick(Sender: TObject); //解析地址
var
temp:String;
strRow:word;
begin
temp:=downloadAddr.Text;
if temp = '' then //判斷是否是空地址
begin
ShowMessage('搜索地址無(wú)效!');
Exit;
end;
temp:=StringReplace(temp,'song','widget/xml-single/sid',[rfReplaceAll]); //XML 解析
temp:=GetWebPage(temp); //獲取URL源代碼
Delete(temp,1,Pos('<song_name>',temp)+19);
songName:=Copy(temp,1,Pos(']',temp)-1); //獲取歌曲名字
Delete(temp,1,Pos('<album_name>',temp)+20);
albumName:=Copy(temp,1,Pos(']',temp)-1); //獲取歌曲所屬專輯名字
Delete(temp,1,Pos('<artist_name>',temp)+21);
artistName:=Copy(temp,1,Pos(']',temp)-1); //獲取歌手名字
Delete(temp,1,Pos('<location>',temp)+18);
strRow:=word(StrToInt(LeftStr(temp,1))); //獲取凱撒矩陣的行
downloadAddrStr:=Copy(temp,2,Pos(']',temp)-2); //獲取歌曲偽地址
//downloadAddr.Text:=downloadAddrStr; //調(diào)試用
downloadAddrStr:=CaesarShifts(downloadAddrStr,strRow); //解析歌曲地址
temp:=Copy(downloadAddrStr,1,Pos('mp3',downloadAddrStr)+2);
downloadName:=RightStr(temp,Pos('/',ReverseString(temp))-1); //獲取默認(rèn)文件名稱
//下面保存ini,txt文件
SaveIniFile('Download Info.ini',downloadName,artistName,SongName,AlbumName);
//記錄:ini文件名,默認(rèn)下載文件名,藝術(shù)家,作曲名,專輯名
SaveTxtFile('Download Path.txt',downloadAddrStr);
//記錄:下載地址
end;
//************************ 點(diǎn)擊粘到剪貼板按鈕 *****************************************//
procedure TForm1.clipBtnClick(Sender: TObject); //復(fù)制到剪貼板
var
path,temp,downloadAddrTemp:string;
txtFile:Textfile;
begin
downloadAddrTemp:='';//初始化剪貼板緩存
clipboard.AsText:='';//清空剪貼板內(nèi)容
path:=ExtractFilePath(Application.Exename)+'Download Path.txt';
AssignFile(txtFile,path);
Reset(txtFile); //打開讀取txt
SetLength(temp,5); //初始化數(shù)組長(zhǎng)度
while not eof(txtFile) do
begin
Readln(txtFile,temp);
downloadAddrTemp:=downloadAddrTemp+temp+#13#10;
end;
clipboard.AsText:=downloadAddrTemp; //下載地址復(fù)制到剪貼板
CloseFile(txtFile);
end;
//************************ 點(diǎn)擊改名并分類按鈕 *****************************************//
procedure TForm1.changNameBtnClick(Sender: TObject); //批量改名
var
path,downloadNametemp,artistNametemp,songNametemp,albumNametemp:string;
oldName,newName:string;
iniFile:TIniFile;
I,countI:Integer;
SearchRec:TSearchRec;
dirPath:string;
begin
if (downloaderSaveDir.Text = '') or (musicLibraryDir.Text = '') then
begin
ShowMessage('請(qǐng)確認(rèn)下載保存目錄和音樂(lè)庫(kù)路徑是否正確!');
Exit;
end;
path:=ExtractFilePath(Application.Exename)+'Download Info.ini';
iniFile:=Tinifile.Create(path);
countI:=iniFile.ReadInteger('已有','首歌',countI); //獲取歌曲數(shù)目
for I := 0 to (countI-1) do
begin
downloadNametemp:=iniFile.ReadString('默認(rèn)文件名',IntToStr(I),downloadNametemp);
if Pos(':',dlAlbumName) > 0 then
dlAlbumName:=StringReplace(dlAlbumName,':','-',[rfReplaceAll]);//防止命名有:
artistNametemp:=iniFile.ReadString('藝術(shù)家',IntToStr(I),artistNametemp);
songNametemp:=iniFile.ReadString('作曲名',IntToStr(I),songNametemp);
albumNametemp:=iniFile.ReadString('專輯名',IntToStr(I),albumNametemp);
if FindFirst(downloaderSaveDir.Text+'\'+downloadNametemp,faAnyFile,SearchRec) =0 then
begin //查找相同名字文件
repeat
newName:=downloaderSaveDir.Text+'\'+artistNametemp+' - '+songNametemp+RightStr(downloadNametemp,4);
RenameFile(downloaderSaveDir.Text+'\'+SearchRec.Name,newName); //文件改名
dirPath:=musicLibraryDir.Text+'\'+artistNametemp+'\'+albumNametemp;//在F盤下QQ音樂(lè)下載目錄新建分類目錄文件夾
//目錄格式: 藝術(shù)家\專輯名\作曲名
ForceDirectories(dirPath);
//downloadAddr.Text:=dirPath; //調(diào)試用
MoveFile(PChar(newName),PChar(dirPath+RightStr(newName,Length(newName)-5))); //移動(dòng)文件到新建目錄
until(FindNext(SearchRec)<>0);
FindClose(SearchRec);
end;
end;
iniFile.Free;
end;
//************************ 點(diǎn)擊清理記錄按鈕 *****************************************//
procedure TForm1.deleteBtnClick(Sender: TObject); //刪除txt、ini文件
var
path:string;
txtFile:Textfile;
iniFile:TIniFile;
begin
path:=ExtractFilePath(Application.Exename)+'Download Path.txt';
DeleteFile(path);
path:=ExtractFilePath(Application.Exename)+'Download Info.ini';
DeleteFile(path);
end;
//******************* 凱撒移位函數(shù),返回明碼 *************************//
function TForm1.CaesarShifts(str: string; row: word): string; //凱撒移位,返回值為明碼
var
arr1:array of char;
arr2:array of array of char;
len,n:Integer;
col,remainder,I,J:word;
begin
len:=Length(str); //字符串長(zhǎng)度
SetLength(arr1,len); //初始化數(shù)組長(zhǎng)度
for I := 0 to (len-1) do //字符串轉(zhuǎn)數(shù)組
arr1[I]:=str[I+1];
DivMod(len,row,col,remainder);
if remainder <> 0 then //有余數(shù),即沒(méi)填滿矩陣
begin
col:=col+1;
remainder:=word(col*row-len); //多出remainder個(gè)
end;
SetLength(arr2,row,col);
n:=0;
for I := 0 to (row-1) do
for J := 0 to (col-1) do
begin
if (I >= (row-remainder)) and (J >= (col-1)) then
begin
arr2[I,J]:=' ';
end
else
begin
arr2[I,J]:=arr1[n]; //矩陣賦值
inc(n);
end;
end;
n:=0;
for J := 0 to (col-1) do
for I := 0 to (row-1) do
begin
if n<len then
Result:=Result+arr2[I,J]; //數(shù)組轉(zhuǎn)字符串
inc(n);
end;
Result:=URLDecode(Result);
Result:=StringReplace(Result,'^','0',[rfReplaceAll]); //替換^為0
end;
//******** 監(jiān)視剪貼板,方便搜索地址欄完成自動(dòng)粘貼,一條一條的復(fù)制粘貼很麻煩的 ************//
procedure TForm1.WMDrawClipBoard(var AMessage: TMessage); //監(jiān)視剪貼板
begin
SendMessage(NextClipHwnd,AMessage.Msg,AMessage.WParam,AMessage.LParam);
//將WM_DRAWCLIPBOARD消息傳遞到下一個(gè)觀察鏈中的窗口
if Clipboard.HasFormat(CF_TEXT) or Clipboard.HasFormat(CF_OEMTEXT) or Clipboard.HasFormat(CF_UNICODETEXT) then
begin
if Pos('www.xiami.com/song',Clipboard.AsText) > 0 then //過(guò)濾不是蝦米音樂(lè)的內(nèi)容
begin
if Clipboard.AsText = clipTemp then
ShowMessage('鏈接已復(fù)制粘貼!');
downloadAddr.Text:=Clipboard.AsText;
clipTemp:=Clipboard.AsText;
end;
end;
end;
//********************************************************************************//
//********************************************************************************//
運(yùn)行效果:
由于迅雷有監(jiān)視剪貼板的功能,所以很方便,點(diǎn)了下“粘到剪貼板”,新建任務(wù)窗口就呼出來(lái)了
Download Info.ini 歌曲信息查看,可以看出 中文,英文,日文均顯示正常,韓文顯示成問(wèn)號(hào)了,是保存編碼問(wèn)題,要用Unicode去寫入,沒(méi)試成功,也不會(huì)寫到ini文件,寫到txt文件中又感覺(jué)不好看,算了,這Bug
Download Path.txt 真實(shí)下載地址查看
下載成功!
改名到分類目錄就不貼了
|
|