上一篇博客先获取到了百度风云榜这个界面的HTML代码
但是这些HTML代码中无用的数据很多,甚至还有广告之类的,所以这一次我们要用
Html Agility Pack筛选出有用的数据
还是先上代码
//url是http://top.baidu.com/buzz?b=1&fr=topindex
string strHTML = WebHelper.GetHtml(target.Url, Encoding.GetEncoding("gbk"));//整個網址的HTML代碼
HtmlDocument doc = new HtmlDocument();//將回應的html流用 Html Agility Pack 解析
doc.LoadHtml(strHTML);//加载HTML代码
HtmlNodeCollection htmlNodeTitle = doc.DocumentNode.SelectNodes("//td[@class='keyword']/a[1]");//返回群組
if (htmlNodeTitle == null)
{
return null;
}
还是debug看一下
可以看到一共有50条数据,可能现在会有人有疑问,//td[@class=‘keyword’]/a[1]这一段话是什么意思
XPath语法
当时我看完XPath语法的时候,其实是有点懵逼的,我以前就对相对路径绝对路径,父级,子集这类东西不怎么清楚,现在又是找父标签,兄弟标签,子标签等等等等,整个人都不好了。不过我还是硬着头皮讲得通俗一点
首先打开谷歌浏览器,F12
谷歌浏览器有一个金手指,可以直接帮你写好XPath语句
//*[@id=“main”]/div[2]/div/table/tbody/tr[2]/td[2]/a[1]
这是复制下来的XPath语句,这个语句就可以帮我们定位到 "男版高颜值通缉犯"的a标签了
然而问题来了,一共50个热搜,我不可能50个标题挨个复制XPath语句吧,我希望一条语句把50个标题都定位到,怎么办呢,找规律。
不得不说程序猿人均逻辑鬼才,想逻辑,找规律基本上是每天要做的事情
首先看热搜榜第一标题的HTML代码
然后是榜二的HTML代码
然后可以发现一个规律,所有的标题都是放在class名为Keyword的td标签下面,并且是td下面的第一个a标签,看到这里,再想想上面代码中写到的//td[@class=‘keyword’]/a[1],是不是突然明白了这段话的意思了?大意就是,所有class属性='keyword’的td标签下面的第一个a标签。这里下标[1]就是第一个的意思,不是数组的下标[1]代表第二个。
现在,htmlNodeTitle里面有50条数据,怎么提取标题和文章链接呢
一个循环完事,以热搜榜一举例,定位到的a标签是这个
<a class="list-title" target="_blank" href="http://www.baidu.com/baidu?cl=3&tn=SE_baiduhomet8_jmjb7mjw&rsv_dl=fyb_top&fr=top1000&wd=%C4%D0%B0%E6%B8%DF%D1%D5%D6%B5%CD%A8%BC%A9%B7%B8" href_top="./detail?b=1&c=513&w=%C4%D0%B0%E6%B8%DF%D1%D5%D6%B5%CD%A8%BC%A9%B7%B8">男版高颜值通缉犯</a>
string[] title = new string[htmlNodeTitle.Count];//標題的集合
for (int i = 0; i < htmlNodeTitle.Count; i++)//將返回的所有標題遍歷
{
title[i] = htmlNodeTitle[i].InnerText.ToString().Trim();//標題獲取純文本
}
InnerText.ToString();获取的是这个a标签的纯文本,最终存入数组的就是 男版高颜值通缉犯
看看最终数组里的数据
那么网址怎么获取呢,网址在a标签里的href属性里面
string[] href = new string[htmlNodeHref.Count];//鏈接的集合
for (int i = 0; i < htmlNodeHref.Count; i++)//將所有標題對應的鏈接遍歷
{
href[i] = htmlNodeHref[i].Attributes["href"].Value.ToString();//獲取href標籤
}
同样看看效果
最后将代码给大家总结一下
首先是获取一个网址HTML代码的方法GetHtml()
public static string GetHtml(string url, Encoding encoding)//網址,編碼格式
{
string html = string.Empty;
try
{
string urlStr = url; //設定要獲取的地址
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(urlStr); //建立HttpWebRequest對象
request.Timeout = 60000; //定義服務器超時時間
~~//这一段是可以不要的,除非你们需要上网账号
WebProxy proxy = new WebProxy(); //定義一個網關對象
proxy.Address = new Uri("http://xx.xx.xx.x:xxxx"); //網關服務器:端口
proxy.Credentials = new NetworkCredential("userId", "password"); //用戶名,密碼
request.UseDefaultCredentials = true; //啟用網關認証
request.Proxy = proxy; //設置網關
~~
if ((HttpWebResponse)request.GetResponse()== null)//如果該網站不存在或被刪除,則返回空html代碼
{
return "";
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse(); //取得回應
Stream stream = response.GetResponseStream(); //得到回應的流對象
StreamReader reader = new StreamReader(stream, encoding); //以xxx編碼讀取流
html = reader.ReadToEnd();
}
catch(Exception ex) {
return "";
throw ex;
}
//sr.Close();
return html;
}
然后是筛选信息,存储的方法
//url是http://top.baidu.com/buzz?b=1&fr=topindex
string strHTML = WebHelper.GetHtml(target.Url, Encoding.GetEncoding("gbk"));//整個網址的HTML代碼
HtmlDocument doc = new HtmlDocument();//將回應的html流用 Html Agility Pack 解析
doc.LoadHtml(strHTML);//加载HTML代码
HtmlNodeCollection htmlNodeTitle = doc.DocumentNode.SelectNodes("//td[@class='keyword']/a[1]");//返回群組
if (htmlNodeTitle == null)
{
return null;
}
string[] title = new string[htmlNodeTitle.Count];//標題的集合
for (int i = 0; i < htmlNodeTitle.Count; i++)//將返回的所有標題遍歷
{
title[i] = htmlNodeTitle[i].InnerText.ToString().Trim();//標題獲取純文本
}
string[] href = new string[htmlNodeHref.Count];//鏈接的集合
for (int i = 0; i < htmlNodeHref.Count; i++)//將所有標題對應的鏈接遍歷
{
href[i] = htmlNodeHref[i].Attributes["href"].Value.ToString();//獲取href標籤
}