现在的位置: 首页 > 综合 > 正文

HtmlAgilityPack.dll爬虫获取百度音乐批量下载地址(C#源码)

2013年12月01日 ⁄ 综合 ⁄ 共 4659字 ⁄ 字号 评论关闭

      关于分析的过程和思路参考原来的一篇文章 《HtmlAgilityPack 爬虫批量获取百度音乐下载地址一

       http://blog.csdn.net/witch_soya/article/details/8316194

      

     源代码下载地址  C#获取百度音乐地址源码

首先在工程中添加引用 HtmlAgilityPack.dll


定义一首歌曲的结构

public class sMp3
        {
           public sMp3() { }
           public string strSid;//sid
           public string strDownPage;//下载页面
           public string strEdition;//专辑名称
           public string strSinger;//歌手名称
           public string strUrl;//下载地址
        }

在一个列表中存放所有需要解析的歌曲地址

List<sMp3> listSongs = new List<sMp3>();

新建一个HtmlAgilityPack.HtmlDocument对象 用来获取和解析HTML页面
HtmlAgilityPack.HtmlDocument hdoc_Main = new HtmlAgilityPack.HtmlDocument();

定义需要操作的XPath路径

 //主页
         string Baidu_Music_MainPage_strUrl   = "http://music.baidu.com/";
         string Baidu_Music_MainPage_Label    = "a";
         string Baidu_Music_MainPage_Value    = "sid";
         string Baidu_Music_MainPage_strXpath = "./html[1]/body[1]/div[4]/div[1]/div[1]/div[2]/div[3]/div[1]/div[1]";
         //下载的页面 如 http://music.baidu.com/song/31496563/download
         string Baidu_Music_DownMusic_strXpath="./html[1]/body[1]/div[1]/div[4]";         
         string Baidu_Music_DownMusic_Label   = "a";
         string Baidu_Music_DownMusic_Value   = "href";

         string Baidu_Music_DownMusic_strXpath_Title = "./html[1]/body[1]/div[1]/div[2]";         
         string Baidu_Music_DownMusic_Title   = "title";

至于这些Xpath路径是怎么来的..可以通过查看源代码的方式,.也可以通过我之前发布的XPath工具(XPathTool)来查看得到。

XpathTool介绍地址  http://blog.csdn.net/witch_soya/article/details/8486893

XPathTool下载地址  http://download.csdn.net/detail/witch_soya/4978587

核心函数之一 :getLabelVal  这个函数接受一个 HtmlAgilityPack.HtmlDocument,实际上就是指定了要解析的HTML文件,strXpath是指定的Xpath语句,这样就能通过Xpath截取HTML中一部分内容了。然后通过 strLabel和strValue 两个参数在截取出来的内容中提取需要的指定标签的指定属性值。比如  HtmlAgilityPack.HtmlDocument 加载了一个html文档,通过strXpath就获取了该HTML文档中的一个区域  如果指定strLabel为 “a”strValue为”href”那么,返回的Arraylist就是该区域中a标签的所有超链接地址

private ArrayList getLabelVal(HtmlAgilityPack.HtmlDocument dc, string strXpath, string strLabel, string strValue)
        {
            ArrayList Arr_Label_Val = new ArrayList();
            //获取指定的节点
            HtmlNode node = dc.DocumentNode.SelectSingleNode(strXpath);
            if (node == null)
            {
                return null;
            }
            string strXPathLabel_Val = "descendant::" + strLabel;

           #region 
            try
            {
                //HtmlNodeCollection atts  = node.SelectNodes("//*[@background or @lowsrc or @src or @href]");
                //这样得到的是基于全文的
                //HtmlNodeCollection hrefs = node.SelectNodes("//a[@href]");
                //这样得到的是基于本节点的                                
                HtmlNodeCollection hrefs = node.SelectNodes(strXPathLabel_Val);
                if (hrefs == null)
                {
                    return null;
                }

                foreach (HtmlNode href in hrefs)
                {
                    if (href.Attributes[strValue] == null)
                    {
                        continue;
                    }
                    //这里得到了歌曲的sid
                    String strSid = href.Attributes[strValue].Value;
                    Arr_Label_Val.Add(strSid);                    
                }

            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
            finally
            {
                // f2.Show();
                
            }
        #endregion
            return Arr_Label_Val;
        }

//获取百度音乐地址
        private void button1_Click(object sender, EventArgs e)
        {     
            HtmlWeb hw = new HtmlWeb();
            string url = Baidu_Music_MainPage_strUrl;
            try
            {
                hdoc_Main = hw.Load(url);
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.ToString());
                return;
            }

            //解析百度音乐主页面 取得a标签的sid 
           Arr_sid  =  getLabelVal(hdoc_Main,Baidu_Music_MainPage_strXpath, Baidu_Music_MainPage_Label, Baidu_Music_MainPage_Value);
           if (Arr_sid == null)
           {
               MessageBox.Show("解析主页面标签错误");
               return;
           }
            for (int i = 0; i < Arr_sid.Count; i++)
            {
                sMp3 sMp3Song = new sMp3();                
                sMp3Song.strSid = Arr_sid[i].ToString();
                
                //组装地址
                string strDownLoadPage = "http://music.baidu.com/song/" + Arr_sid[i] + "/download";
                sMp3Song.strDownPage = strDownLoadPage;
                listSongs.Add(sMp3Song);
            }
            
            //解析 下载音乐 网页
            Thread th = new Thread(DownLoadArrPage);
            th.Start();
        }


//解析网页
        public delegate void MyInvoke(string str1, string str2,string str3);
        private void DownLoadArrPage()
        {
            MyInvoke mi = new MyInvoke(UpdateForm);            
            HtmlWeb hw = new HtmlWeb();
            
            for (int i = 0; i < listSongs.Count(); i++)
            {
                string strUrl =(listSongs[i].strDownPage).ToString();
                HtmlAgilityPack.HtmlDocument hdoc_DownPage = hw.Load(strUrl);
                ArrayList Arr_DownLoadUrl =  getLabelVal(hdoc_DownPage,Baidu_Music_DownMusic_strXpath, Baidu_Music_DownMusic_Label, Baidu_Music_DownMusic_Value);
                //实际上这个Arry_DownLoadUrl返回的只有一条超链接数据 不用遍历了。
                listSongs[i].strUrl = Arr_DownLoadUrl[0].ToString();
                ArrayList Arr_Title = getLabelVal(hdoc_DownPage, Baidu_Music_DownMusic_strXpath_Title, Baidu_Music_DownMusic_Label, Baidu_Music_DownMusic_Title);
                listSongs[i].strEdition = Arr_Title[0].ToString();
                listSongs[i].strSinger = Arr_Title[1].ToString();
            }

            //Arry_Downloadurl存放的是   /data/music/file?link=http://zhangmenshiting.baidu.com/data2/music/31626527/3149656368400128.mp3?xcode=4b1b6b4117b45f71b5949db22586f5d7 这种内容
            for (int i = 0; i < listSongs.Count(); i++)
            {
                string strUrl = (listSongs[i].strUrl).ToString();

                //正则表达式
                //@"demo_class.asp\?sort=([^x00-xff]{4})&id\=([a-z0-9]+)";
                Regex reg = new Regex(@"http://(.*[a-zA-Z0-9_])");
                var result = reg.Match(strUrl).Groups;
                foreach (var item in result)
                {
                     //   listSongs[i].strUrl = item;
                    if (item.ToString().Contains("http://") == false)
                    {
                        continue;
                    }
                    //将内容添加到列表框 第一个列表框                    
                    this.BeginInvoke(mi, new Object[] { listSongs[i].strEdition,listSongs[i].strSinger, item.ToString() });
                    listSongs[i].strUrl = item.ToString();

                }
                
            }
        }

代码不多,个人感觉流程还是比较清晰的。就不多说了。供新手参考。



/ *********************witch2013年1月10日9:31:53******************************/

抱歉!评论已关闭.