最近研究C#下面的网页抓取信息:最开始使用的DotnetSpider工具包进行抓取,使用不到一个星期每次抓取回来都是空(由于封装逻辑复杂,就不打算使用了).然后就使用HtmlAgilityPack进行网页数据获取,如果循环访问的网页数量不多可以使用这个,但是数量一多,这个工具也会出现抓取数据失败的情况。
最后采用的解决方案是使用HttpWebRequest访问浏览器返回网页数据,然后使用HtmlAgilityPack加载网页数据解析相应的字段内容和属性内容:
1. 这个是使用HttpWebRequest获取需要访问浏览器的网页内容:
public static string GetHtml(string url)
{
string Html = string.Empty;
HttpWebRequest Request = (HttpWebRequest)WebRequest.Create(url);
Request.KeepAlive = true;
Request.ProtocolVersion = HttpVersion.Version11;
Request.Method = "GET";
Request.Accept = "*/* ";
Request.UserAgent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.56 Safari/536.5";
Request.Referer = url;
HttpWebResponse htmlResponse = await Request.GetResponseAsync() as HttpWebResponse;
Stream htmlStream = htmlResponse.GetResponseStream();
StreamReader weatherStreamReader = new StreamReader(htmlStream, Encoding.UTF8);
Html = weatherStreamReader.ReadToEnd();
weatherStreamReader.Close();
htmlStream.Close();
htmlResponse.Close();
return Html;
}
2. 使用HtmlAgilityPack(使用HtmlAgilityPack需要在Nuget程序包中安装HtmlAgilityPack 1.11.28版本)加载网页数据解析相应的字段内容和属性内容:
public static void TestData(string url)
{
var htmlText = await GetHtml(url);
if (htmlText!= null)
{
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(htmlText);
//内容解析-获得所有的类别
HtmlNode titleNode = doc.DocumentNode.SelectSingleNode("//div[@id='blogTitle']/h2");
Console.WriteLine("titleNode:" + titleNode.InnerText);
//获取属性的值
string urlhref = doc.DocumentNode.SelectSingleNode("//div[@id='header']/div[@id='blogTitle']/a").Attributes["href"].Value;
Console.WriteLine("urlhref:" + urlhref);
//获取标签的内容
string url2 = doc.DocumentNode.SelectSingleNode("//div[@id='blogTitle']/h2").InnerText;
Console.WriteLine("url2:" + url2);
//获取集合的内容
HtmlNodeCollection list = doc.DocumentNode.SelectNodes("//ul[@id='navList']/li");
//根据xpath获取列表
foreach (var data in list)
{
HtmlNode node = HtmlNode.CreateNode(data.OuterHtml);
HtmlNode a = node.SelectSingleNode("//a");
Console.WriteLine("navList:" + a.InnerText);
}
}
}
3.调用方式:
public static void Test()
{
string _url = "http://www.cnblogs.com/xuliangxing/";
TestData(url);
}
特别注意:如果循环网页数据多,建议在调用网页返回数据时使用 System.Threading.Thread.Sleep(3000);停留几秒钟,如果不停留几秒钟会出现返回为空的情况。