c#抓取网页数据( 为什么要了解百度新闻中热点要闻版块提高站点百度排名)

优采云 发布时间: 2022-04-06 19:10

  c#抓取网页数据(

为什么要了解百度新闻中热点要闻版块提高站点百度排名)

  

  图1

  如图1所示,在我们的工作过程中,无论是平台网站还是公司官网,总会有新闻展示。比如某天产品经理告诉我们,推广员想抢百度新闻的热点新闻版块,以提高网站的百度排名。要抢百度热点新闻版,首先要了解站点请求头(Request headers)信息。

  为什么要了解请求标头(Request headers)信息?

  原因在于,我们可以根据请求头信息中的某部分消息信息,而不是通过人工爬虫程序规避站点屏蔽,来伪装这是一个正常的HTTP请求,成功获取响应数据(Response data)。

  如何查看百度新闻URL的请求头信息?

  

  图 2

  如图2,我们可以打开谷歌浏览器或者其他浏览器开发工具(按F12)查看站点的请求头消息信息。从图中可以看出百度新闻站点可以接受文本/html 等数据类型;语言为中文;浏览器版本为 Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 ( KHTML,如 Gecko ) Chrome/66.0.3359.181 Safari/537.36 等消息信息,我们在发起 HTTP 时直接携带消息信息request 过去,当然不是每一个包信息参数都必须携带过去,一部分可以被成功请求。

  那么什么是响应数据?

  

  图 3

  如图3所示,响应数据(Response data)可以从谷歌浏览器或者其他浏览器开发工具中查看(按F12)查看,响应可以是数据或者DOM树数据,方便我们的后续分析数据。

  当然,你可以学习任何开发语言来开发爬虫程序:C#、NodeJs、python、java、C++。

  不过这里主要讲C#爬虫程序的开发。微软为我们提供了HTTP请求的两个HttpWebRequest和HttpWebResponse对象,方便我们发送请求获取数据。下面显示了 C# HTTP 请求代码:

   private string RequestAction(RequestOptions options)

{

string result = string.Empty;

IWebProxy proxy = GetProxy();

var request = (HttpWebRequest)WebRequest.Create(options.Uri);

request.Accept = options编程客栈.Accept;

//在使用curl做POST的时候, 当要POST的数据大于1024字节的时候, curl并不会直接就发起POST请求, 而是会分为俩步,

//发送一个请求, 包含一个Expect: 100 -continue, 询问Server使用愿意接受数据

//接收到Server返回的100 - continue应答以后, 才把数据POST给Server

//并不是所有的Server都会正确应答100 -continue, 比如lighttpd, 就会返回417 “Expectation Failed”, 则会造成逻辑出错.

request.ServicePoint.Expect100Continue = false;

request.ServicePoint.UseNagleAlgorithm = false;//禁止Nagle算法加快载入速度

if (!string.IsNullOrEmpty(options.XHRParams)) { request.AllowWriteStreamBuffering = true; } else { request.AllowWriteStreamBuffering = false; }; //禁止缓冲加快载入速度

request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate");//定义gzip压缩页面支持

request.ContentType = options.ContentType;//定义文档类型及编码

request.AllowAutoRedirect = options.AllowAutoRedirect;//禁止自动跳转

request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebhttp://www.cppcns.comKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36";//设置User-Agent,伪装成Google Chrome浏览器

request.Timeout = options.Timeout;//定义请求超时时间为5秒

request.KeepAlive = options.KeepAlive;//启用长连接

if (!string.IsNullOrEmpty(options.Referer)) request.Referer = options.Referer;//返回上一级历史链接

request.Method = options.Method;//定义请求方式为GET

if (proxy != null) request.Proxy = proxy;//设置代理服务器IP,伪装请求地址

if (!string.IsNullOrEmpty(options.RequestCookies)) request.Headers[HttpRequestHeader.Cookie] = options.RequestCookies;

request.ServicePoint.ConnectionLimit = options.ConnectionLimit;//定义最大连接数

if (options.WebHeader != null && options.WebHeader.Count > 0) request.Headers.Add(options.WebHeader);//添加头部信息

if (!string.IsNullOrEmpty(options.XHRParams))//如果是POST请求,加入POST数据

{

byte[] buffer = Encoding.UTF8.GetBytes(options.XHRParams);

if (buffer != null)

{

request.ContentLength = buffer.Length;

request.GetRequestStream().Write(buffer, 0, buffer.Length);

}

}

using (var response = (HttpWebResponse)request.GetResponse())

{

////获取请求响应

//foreach (Cookie cookie in response.Cookies)

// options.CookiesContainer.Add(cookie);//将Cookie加入容器,保存登录状态

if (response.ContentEncoding.ToLower().Contains("gzip"))//解压

{

using (GZipStream stream = new GZipStream(response.GetResponseStream(), CompressionMode.Decompress))

{

using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))

{

result = reader.ReadToEnd();

}

}

}

else if (response.ContentEncoding.ToLower().Contains("deflate"))//解压

{

using (DeflateStream stream = new DeflateStream(response.GetResponseStream(), CompressionMode.Decompress))

{

using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))

{

result = reader.ReadToEnd();

}

}

}

else

{

using (Stream stream = response.GetResponseStream())//原始

{

using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))

{

result = reader.ReadT编程客栈oEnd();

}

}

}

}

request.Abort();

return result;

}

  还有一个我传入的自定义对象。当然,传入或传出对象由你根据实际业务需求定义:

   public class RequestOptions

{

///

/// 请求方式,GET或POST

///

public string Method { get; set; }

///

/// URL

///

public Uri Uri { get; set; }

///

/// 上一级历史记录链接

///

public string Referer { get; set; }

///

/// 超时时间(毫秒)

///

public int Timeout = 15000;

///

/// 启用长连接

///

public bool KeepAlive = true;

///

/// 禁止自动跳转

///

public bool AllowAutoRedirect = false;

/// &http://www.cppcns.comlt;summary>

/// 定义最大连接数

///

public int ConnectionLimit = int.MaxValue;

//编程客栈/

/// 请求次数

///

public int RequestNum = 3;

///

/// 可通过文件上传提交的文件类型

///

public string Accept = "*/*";

///

/// 内容类型

///

public string ContentType = "application/x-www-form-urlencoded";

///

/// 实例化头部信息

///

private WebHeaderCollection header = new WebHeaderCollection();

///

/// 头部信息

///

public WebHeaderCollection WebHeader

{

get { return header; }

set { header = value; }

}

///

/// 定义请求Cookie字符串

///

public string RequestCookies { get; set; }

///

/// 异步参数数据

///

public string XHRParams { get; set; }

}

  根据显示的代码,我们可以发现 HttpWebRequest 对象封装了很多 Request headers 消息参数。我们可以根据网站的Request headers信息在微软提供的HttpWebRequest对象中设置(见代码消息参数注释,都写了相关参数说明,如果理解有误,请告知,谢谢你),然后发送请求获取响应数据来解析数据。

  还补充一点,爬虫程序最好使用代理IP来使用代理IP,这样可以降低被屏蔽的概率,提高爬取效率。但是,代理IP也分为质量等级。对于某些 HTTPS 站点,可能需要质量级别更高的代理 IP 才能穿透。我不会在这里跑题。我会写一篇关于代理IP质量等级的文章文章详情说说我的看法。

  C#代码如何使用代理IP?

  Microsoft NET 框架还为我们提供了一个使用代理 IP 的 System.Net.WebProxy 对象。使用代码如下:

   private System.Net.WebProxy GetProxy()

{

System.Net.WebProxy webProxy = null;

try

{

// 代理链接地址加端口

string proxyHost = "192.168.1.1";

string proxyPort = "9030";

// 代理身份验证的帐号跟密码

//string proxyUser = "xxx";

//string proxyPass = "xxx";

// 设置代理服务器

webProxy = new System.Net.WebProxy();

// 设置代理地址加端口

webProxy.Address = new Uri(string.Format("{0}:{1}", proxyHost, proxyPort));

// 如果只是设置代理IP加端口,例如192.168.1.1:80,这里直接注释该段代码,则不需要设置提交给代理服务器进行身份验证的帐号跟密码。

//webProxy.Credentials = new System.Net.NetworkCredential(proxyUser, proxyPass);

}

catch (Exception ex)

{

Console.WriteLine("获取代理信息异常", DateTime.Now.ToString(), ex.Message);

}

return webProxy;

}

  关于System.Net.WebProxy对象的参数说明,我也在代码中进行了说明。

  如果获取的Response数据是json、xml等格式的数据,这里就不详细描述这种数据解析方式了,请自行百度。这里的主要主题是 DOM 树 HTML 数据的解析。对于这类数据,有的人会使用正则表达式来解析,有的人会使用组件。当然,只要你能得到你想要的数据,你就可以按照你想要的方式解析它。这里的重点是我经常使用解析组件HtmlAgilityPack,参考DLL是(使用HtmlAgilityPack)。解析代码如下:

   HtmlDocument htmlDoc = new HtmlDocument();

htmlDoc.LoadHtml(simpleCrawlResult.Contents);

HtmlNodeCollection liNodes = htmlDoc.DocumentNode.SelectSingleNode("//div[@id='pane-news']").SelectSingleNode("div[1]/ul[1]").SelectNodes("li");

if (liNodes != null && liNodes.Count > 0)

{

for (int i = 0; i < liNodes.Count; i++)

{

string title = liNodes[i].SelectSingleNode("strong[1]/a[1]").InnerText.Trim();

string href = liNodes[i].SelectSingleNode("strong[1]/a[1]").GetAttributeValue("href", "").Trim();

Console.WriteLine("新闻标题:" + title + ",链接:" + href);

}

}

  下面主要展示爬取结果。

  

  图 4

  如图4,抓包效果,一个简单的爬虫程序就这样完成了。

  至此,这篇关于c#实现爬虫程序的文章文章就介绍到这里了。希望对您的学习有所帮助,也希望您多多支持。

  本文标题:c#实现爬虫程序

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线