• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            聚星亭

            吾笨笨且懶散兮 急須改之而奮進(jìn)
            posts - 74, comments - 166, trackbacks - 0, articles - 0
              C++博客 :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

            難得我母親要我給她下音樂(lè)聽(tīng),她在好聽(tīng)音樂(lè)網(wǎng)上聽(tīng)到一首,我就要百度好久才能找到播放的是哪首,好長(zhǎng)時(shí)間才下了僅僅的幾首。
            記得以前迅雷可以直接分析出下載地址來(lái)的,可是現(xiàn)在不知怎么的,迅雷的版本高了,功能卻變得弱智了。
            沒(méi)有辦法就只有自己找找規(guī)律分析一下了,下面記錄我的分析過(guò)程,貼出來(lái)紀(jì)念下:

            先看下網(wǎng)址的規(guī)律:
            多個(gè)歌曲連播的URL地址形式:
            http://www.haoting.com/play/htsonglian1.htm?id=123907&id=357857
            其中id=后面的數(shù)字就是歌曲的ID。


            單首歌曲播放的URL形式:
            http://www.haoting.com/htmusic/357857ht.htm
            其中的數(shù)字就是歌曲的ID。

            查看其源文件,得到如下內(nèi)容:

            <SCRIPT language="JavaScript" src="/js/lianbohy.js"></SCRIPT>


            打開(kāi)這個(gè)文件,查看其代碼,仔細(xì)分析得到有用信息如下:

            function digui(musicids,length)
            {
             
            if(idindex < length)
             {
              idvalue 
            = musicids[idindex];
              s 
            = document.createElement("script");
              s.type
            ="text/javascript";
              s.src
            ="http://haoting.com/musicjs/"+musicids[idindex]+".js"// 這個(gè)是關(guān)鍵。
              document.getElementsByTagName("head")[0].appendChild(s);
             
             }
             
            }

             

            由于到這里兩種網(wǎng)址中歌曲的ID已經(jīng)都取到了只要訪問(wèn)如下格式的URL:
             http://haoting.com/musicjs/歌曲的ID.js
            比如:
             http://haoting.com/musicjs/357857.js

            就可以下載到如下內(nèi)容的JS文件:

            var url_357857="/21z/0/dianxiao2yyyyqx090620/1/0897053676a18e5e_1.wma";  //下載地址
            var music_357857="相愛(ài)后動(dòng)物感傷(CD Version) - 阿密特(張惠妹)";   //這個(gè)是歌曲名
            var singer_357857="最新單曲";       //這個(gè)是歌手名
            var nclassid_357857=5538;
            var specialid_357857="abb60fe6d6c77f45";
            var specialName_357857="最新單曲合輯NO.48";     //這個(gè)是專輯名


            我們知道這個(gè)音樂(lè)在網(wǎng)站上的相對(duì)地址了,怎么才能知道它完整的地址呢?

            繼續(xù)分析lianbohy.js中的代碼,找到如下信息:

             

            //播放歌曲
            function play(str,obj)
            {
             
             
            var STAND_STR = "/19z/",
             STAND_STR2 
            = "/20z/",
             STAND_STR3 
            = "/21z/",
             STAND_STR4 
            = "/22z/";
             
            if(url.indexOf(STAND_STR)==-1 && url.indexOf(STAND_STR2)==-1 && url.indexOf(STAND_STR3)==-1 && url.indexOf(STAND_STR4)==-1)  
              ht 
            = "http://ow.haoting.com";
             
            else 
              ht 
            = "http://wma.haoting.com";
             
             
            if(window.navigator.userAgent.indexOf("MSIE"== -1)
             {
              installPlayer(ht
            +url);
             }
             
            else
             {
              haotingplay.url
            =ht+url;
              haotingplay.controls.play();
              showTLab();
             }
             
            }


            嘿嘿,明白了吧,如果看不懂這些代碼,就把它跟我們找到的地址一起對(duì)比下:
             STAND_STR3 = "/21z/",
             ht = " haotingplay.url=ht+url;
            再看下相對(duì)地址:
             var url_357857="/21z/0/dianxiao2yyyyqx090620/1/0897053676a18e5e_1.wma";


            根據(jù)上面的文件我們可以提取出很多的信息,其中下載地址如下:
            http://wma.haoting.com/21z/0/dianxiao2yyyyqx090620/1/0897053676a18e5e_1.wma

            分析完畢,下面開(kāi)始寫(xiě)個(gè)小程序,讓它自動(dòng)完成我上面的分析過(guò)程并顯示結(jié)果:
            首先需要用程序來(lái)分解上面的網(wǎng)址,從中提取出里面的歌曲ID:

            /************************************************************************/
            // 函數(shù)名稱:    AnalyseXUrl
            // 參數(shù)列表:
            //            1、 pUrl      : 要分析的網(wǎng)址。
            //            2、    desMusicID:    用來(lái)存放歌曲ID的緩沖區(qū)。
            //            3、 desBufLen :    URL中存在歌曲ID的數(shù)量。
            // 函數(shù)功能:
            //                從給定的網(wǎng)址中分離出歌曲的ID。
            // 返回值  :
            //                獲取成功返回TRUE, 否則是FALSE。
            /*
            ***********************************************************************/
            BOOL WINAPI AnalyseXUrl(PCHAR pUrl, PDWORD desMusicID, PDWORD desBufLen)
            {
                
            bool bStart = false;
                
            char tmpID[10= {0};

                
            int UrlLen = lstrlen(pUrl);
                
            if (0 < UrlLen)
                {
                    
            if (NULL != strstr(pUrl, "haoting.com/htmusic/\0"&& NULL != strstr(pUrl, ".htm\0"))
                    {
                        
            //http://www.haoting.com/htmusic/357857ht.htm
                        for (int i = 0, x = 0; i<lstrlen(pUrl); i++)
                        {
                            
            if (pUrl[i] >= '0' && pUrl[i] <= '9')
                            {
                                tmpID[x] 
            = pUrl[i];
                                x
            ++;
                            }        
                        }
                        sscanf(tmpID, 
            "%d", desMusicID);
                        
            *desBufLen = 1;
                        
            return TRUE;
                    } 
                    
            else if(NULL != strstr(pUrl, ".htm?id=\0"))
                    {
                        
            *desBufLen = 0;
                        
            //http://www.haoting.com/play/htsonglian1.htm?id=123907&id=357857
                        for (int i = 0, x = 0; i<lstrlen(pUrl); i++)
                        {
                            
            if (i>=0 && pUrl[i-1== '=')
                            {
                                bStart 
            = true;
                                x 
            = 0;
                            }

                            
            if (pUrl[i] == '&')
                            {
                                bStart 
            = false;
                                sscanf(tmpID, 
            "%d", desMusicID);
                                
            *desBufLen += 1;
                                desMusicID
            ++;
                                RtlZeroMemory(tmpID, 
            10);
                            }

                            
            if (bStart)
                            {
                                tmpID[x] 
            = pUrl[i];
                                x
            ++;
                            }
                        }
                        sscanf(tmpID, 
            "%d", desMusicID);
                        
            *desBufLen += 1;
                        
            return TRUE;
                    }
                    
            else
                    {
                        
            return FALSE;
                    }
                }
                
            else
                {
                    
            return FALSE;
                }
            }
                     OK,成功得到ID我們就可以構(gòu)造一個(gè)網(wǎng)址,得到ID對(duì)應(yīng)歌曲的信息:
            /************************************************************************/
            // 函數(shù)名稱:    GetXCode
            // 參數(shù)列表:    
            //            1、    nMusicID:    指定歌曲的ID
            //            2、 desCode    :    用來(lái)存放HTML代碼的緩沖區(qū)
            // 函數(shù)功能:
            //                獲取指定URL中的HTML代碼。
            // 返回值  :
            //            返回獲取的代碼的字節(jié)數(shù)。
            /*
            ***********************************************************************/
            int WINAPI GetXCode(int nMusicID, PCHAR desCode)
            {
                
            char    szMusicID[10= {0};
                BOOL    bReadFlg 
            = FALSE;
                
            char    MusicXCodeBuf[1024= {0}; 
                DWORD    dwBytesRead 
            = 0
                
            char    pUrl[128]    = "http://haoting.com/musicjs/\0";    //"http://haoting.com/musicjs/"+musicids[idindex]+".js"
                sprintf(szMusicID, "%d", nMusicID);

                lstrcat(pUrl, szMusicID);
                lstrcat(pUrl, 
            ".js\0");

                HINTERNET hNet 
            = ::InternetOpen("Wonderful Songs"//當(dāng)HTTP協(xié)議使用時(shí),這個(gè)參數(shù)隨意賦值 
                    PRE_CONFIG_INTERNET_ACCESS, //訪問(wèn)類型指示W(wǎng)in32網(wǎng)絡(luò)函數(shù)使用登記信息去發(fā)現(xiàn)一個(gè)服務(wù)器。 
                    NULL, 
                    INTERNET_INVALID_PORT_NUMBER, 
            //使用INTERNET_INVALID_PORT_NUMBER相當(dāng)于提供卻省的端口數(shù)。 
                    0 //標(biāo)志去指示使用返回句句柄的將來(lái)的Internet函數(shù)將"不"為回調(diào)函數(shù)發(fā)送狀態(tài)信息 
                    ) ; 
                
                HINTERNET hUrlFile 
            = ::InternetOpenUrl(hNet,    //從InternetOpen返回的句柄 
                    pUrl,    //需要打開(kāi)的URL ,我們要打開(kāi)哪個(gè)網(wǎng)址就可以填到這里
                    NULL,    //用來(lái)向服務(wù)器傳送額外的信息,一般為NULL 
                    0,        //用來(lái)向服務(wù)器傳送額外的信息,一般為 0 
                    INTERNET_FLAG_RELOAD, //InternetOpenUrl行為的標(biāo)志 
                    0) ;    //信息將不會(huì)被送到狀態(tài)回調(diào)函數(shù) 

                bReadFlg 
            = ::InternetReadFile(hUrlFile,        //InternetOpenUrl返回的句柄 
                        MusicXCodeBuf,            //保留數(shù)據(jù)的緩沖區(qū),也就是存放網(wǎng)頁(yè)的內(nèi)容拉
                        sizeof(MusicXCodeBuf), 
                        
            &dwBytesRead);    //指向包含讀入緩沖區(qū)字節(jié)數(shù)的變量的指針; 

                
            if (!bReadFlg)
                {
                    lstrcpy(desCode, 
            "連接超時(shí)\0");
                }
                
            else
                {
                    lstrcpy(desCode, MusicXCodeBuf);
                }


                ::InternetCloseHandle(hUrlFile); 
                ::InternetCloseHandle(hNet); 

                
            return lstrlen(desCode);
            }

            /************************************************************************/
            // 函數(shù)名稱:    AnalyseXCode
            // 參數(shù)列表:    
            //            1、 nMusicID:    歌曲ID。
            //            2、    XCode     :    HTML代碼。
            // 函數(shù)功能:
            //                從JS代碼中分離歌曲的關(guān)鍵信息到結(jié)構(gòu)體中。
            // 返回值  :
            //                返回 SONG_STRU 結(jié)構(gòu),其中存放的歌曲的信息。
            // 參數(shù)的格式:
            //                var url_357857="/21z/0/dianxiao2yyyyqx090620/1/0897053676a18e5e_1.wma";
            //                var music_357857="相愛(ài)后動(dòng)物感傷(CD Version) - 阿密特(張惠妹)";
            //                var singer_357857="最新單曲";
            //                var nclassid_357857=5538;
            //                var specialid_357857="abb60fe6d6c77f45";
            //                var specialName_357857="最新單曲合輯NO.48";
            /*
            ***********************************************************************/
            SONG_STRU WINAPI AnalyseXCode(
            int nMusicID, PCHAR XCode)
            {
                
            bool        bStart = false;
                
            char        *pdest;
                
            char        tmpStr[128]    = {0};
                
            char        szMusicID[10= {0};
                
                SONG_STRU    struMusicInfo ;

                struMusicInfo.id            
            =    nMusicID;
                struMusicInfo.MusicName        
            =    new char[128];
                struMusicInfo.Singer        
            =    new char[128];
                struMusicInfo.specialName    
            =    new char[128];
                struMusicInfo.Url            
            =    new char[128];
                    
                
            if (XCode != NULL)
                {
                    
            //解析下載地址
                    pdest  = strstr(XCode, "url_\0");
                    
            if (NULL != pdest)
                    {
                        
            for (int i = pdest - XCode + 1, x = 0; i<lstrlen(XCode); i++)
                        {
                            
            if (i>=0 && XCode[i-2== '=')
                            {
                                bStart 
            = true;
                                x 
            = 0;
                            }
                            
                            
            if (XCode[i+1== ';')
                            {
                                bStart 
            = false;

                                
            if(strstr(tmpStr, "/19z/\0")==NULL && strstr(tmpStr, "/20z/\0")==NULL && \
                                            strstr(tmpStr, 
            "/21z/\0")==NULL && strstr(tmpStr, "/22z/\0")==NULL)  
                                {
                                    lstrcpy(struMusicInfo.Url, 
            "http://ow.haoting.com");
                                }
                                
            else 
                                {
                                    lstrcpy(struMusicInfo.Url, 
            "http://wma.haoting.com");
                                }
                            
                                lstrcat(struMusicInfo.Url, tmpStr);
                                RtlZeroMemory(tmpStr, 
            128);
                                
            break;
                            }
                            
                            
            if (bStart)
                            {
                                tmpStr[x] 
            = XCode[i];
                                x
            ++;
                            }
                        }
                    }

                    
            //解析歌曲名字
                    pdest  = strstr(XCode, "music_\0");
                    
            if (NULL != pdest)
                    {
                        
            for (int i = pdest - XCode + 1, x = 0; i<lstrlen(XCode); i++)
                        {
                            
            if (i>=0 && XCode[i-2== '=')
                            {
                                bStart 
            = true;
                                x 
            = 0;
                            }
                            
                            
            if (XCode[i+1== ';')
                            {
                                bStart 
            = false;
                                lstrcpy(struMusicInfo.MusicName, tmpStr);
                                RtlZeroMemory(tmpStr, 
            128);
                                
            break;
                            }
                            
                            
            if (bStart)
                            {
                                tmpStr[x] 
            = XCode[i];
                                x
            ++;
                            }
                        }
                    }

                    
            //解析歌手名字
                    pdest  = strstr(XCode, "singer_\0");
                    
            if (NULL != pdest)
                    {
                        
            for (int i = pdest - XCode + 1, x = 0; i<lstrlen(XCode); i++)
                        {
                            
            if (i>=0 && XCode[i-2== '=')
                            {
                                bStart 
            = true;
                                x 
            = 0;
                            }
                            
                            
            if (XCode[i+1== ';')
                            {
                                bStart 
            = false;
                                lstrcpy(struMusicInfo.Singer, tmpStr);
                                RtlZeroMemory(tmpStr, 
            128);
                                
            break;
                            }
                            
                            
            if (bStart)
                            {
                                tmpStr[x] 
            = XCode[i];
                                x
            ++;
                            }
                        }
                    }

                    
            //解析專輯名字
                    pdest  = strstr(XCode, "specialName_\0");
                    
            if (NULL != pdest)
                    {
                        
            for (int i = pdest - XCode + 1, x = 0; i<lstrlen(XCode); i++)
                        {
                            
            if (i>=0 && XCode[i-2== '=')
                            {
                                bStart 
            = true;
                                x 
            = 0;
                            }
                            
                            
            if (XCode[i+1== ';')
                            {
                                bStart 
            = false;
                                lstrcpy(struMusicInfo.specialName, tmpStr);
                                RtlZeroMemory(tmpStr, 
            128);
                                
            break;
                            }
                            
                            
            if (bStart)
                            {
                                tmpStr[x] 
            = XCode[i];
                                x
            ++;
                            }
                        }
                    }
                }

                
            return    struMusicInfo;
            }

                     然后將它得到的信息顯示到程序的界面的就可以了,由于直接顯示在分析的時(shí)候,會(huì)造成界面的暫時(shí)性假死,所以我單獨(dú)拋了個(gè)線程來(lái)完成分析的工作,界面只負(fù)責(zé)顯示,然后在分析的時(shí)候加上等待時(shí)間,以減少對(duì)網(wǎng)絡(luò)和電腦資源的消耗。
                     效果如下圖:


            當(dāng)然,如果大家有興趣,可以寫(xiě)個(gè)程序,通過(guò)對(duì)ID的遍歷來(lái)實(shí)現(xiàn)歌曲搜索、下載等功能,不過(guò)可能會(huì)比較消耗網(wǎng)絡(luò)資源我就不寫(xiě)了,嘿嘿!

            工程下載:/Files/bester/HaotingPlg/GetDownloadUrlPlg.rar

            Feedback

            # re: 好聽(tīng)音樂(lè)網(wǎng) -- 歌曲下載分析流程及程序的編寫(xiě)  回復(fù)  更多評(píng)論   

            2009-06-30 08:05 by besterChen
            這里有另一種寫(xiě)法和分析:
            http://bbs.pediy.com/showthread.php?t=92326

            # re: 好聽(tīng)音樂(lè)網(wǎng) -- 歌曲下載分析流程及程序的編寫(xiě)  回復(fù)  更多評(píng)論   

            2009-12-22 11:01 by 我靠
            靠。會(huì)點(diǎn)小技術(shù),就不要公開(kāi),md,我對(duì)haoting采集大半年了。
            你這個(gè)破技術(shù)公開(kāi),導(dǎo)致好聽(tīng)代碼重新調(diào)整,我又要重寫(xiě)我程序,拜托樓主你還能不要公開(kāi)這點(diǎn)破爛玩意呢。

            # re: 好聽(tīng)音樂(lè)網(wǎng) -- 歌曲下載分析流程及程序的編寫(xiě)  回復(fù)  更多評(píng)論   

            2010-01-13 13:37 by besterChen
            @我靠
            抱歉哦,我不是故意的……

            我就是平時(shí)無(wú)聊,搞個(gè)博客來(lái)顯擺顯擺,裝下牛人~

            僅僅是滿足下自己的虛榮心而已,希望你別往心里去~

            # re: 好聽(tīng)音樂(lè)網(wǎng) -- 歌曲下載分析流程及程序的編寫(xiě)  回復(fù)  更多評(píng)論   

            2010-07-30 05:22 by hoodlum1980
            GetXCode函數(shù)里設(shè)置pUrl的時(shí)候,用一個(gè)sprintf函數(shù)就好了呀,干嗎還要連續(xù)的strcat呢呵呵。。。
            看得出來(lái),lz還是很留戀在C的多字節(jié)字符串處理上(可能和我一樣,用熟了就不喜歡換別的了),不過(guò)我還是建議樓主逐漸適應(yīng)TCHAR上來(lái)(畢竟NT以后的操作系統(tǒng)都采用寬字符了),只需要記得大部分用_tcs開(kāi)頭就是了,基本上所有的多字節(jié)字符串都有 tchar 版本;

            # re: 好聽(tīng)音樂(lè)網(wǎng) -- 歌曲下載分析流程及程序的編寫(xiě)[未登錄](méi)  回復(fù)  更多評(píng)論   

            2010-07-30 18:00 by besterchen
            @hoodlum1980
            恩,是啊~
            我會(huì)注意的,(*^__^*) 嘻嘻……~
            久久影视综合亚洲| 久久天天日天天操综合伊人av| 精品久久久久久久国产潘金莲| 国产高潮久久免费观看| 一本久久免费视频| 久久久国产一区二区三区| 欧美精品一区二区精品久久| 久久精品成人欧美大片| 久久综合丁香激情久久| 国产精品久久久久无码av| 国产韩国精品一区二区三区久久 | 久久99国产一区二区三区| 久久精品国产99国产精偷| 99久久99久久久精品齐齐| 久久99国产综合精品免费| 久久综合给合久久狠狠狠97色| 中文精品久久久久人妻不卡| 99蜜桃臀久久久欧美精品网站 | 青青国产成人久久91网| 国产精品久久久久久福利漫画| 国产99精品久久| 99久久亚洲综合精品网站| 成人国内精品久久久久影院VR| 精品久久久久国产免费| 欧美性大战久久久久久| 亚洲国产天堂久久综合| 亚洲欧美成人综合久久久 | 亚洲乱码中文字幕久久孕妇黑人| 午夜久久久久久禁播电影| 久久久久久国产精品无码超碰 | 久久人人爽人人澡人人高潮AV| 久久久久久亚洲精品不卡| 亚洲国产成人久久一区久久| 久久夜色精品国产噜噜亚洲a| 欧美牲交A欧牲交aⅴ久久| 国产亚洲美女精品久久久久狼| 精品久久久噜噜噜久久久| 国产成人无码精品久久久免费| 亚洲国产成人精品91久久久| 一本色道久久综合狠狠躁| 久久九九亚洲精品|