c#抓取网页数据(在页面抓取时应该注意到的几个问题(图) )

优采云 发布时间: 2022-02-08 00:21

  c#抓取网页数据(在页面抓取时应该注意到的几个问题(图)

)

  在本文中,我们将讨论抓取页面时应注意的几个问题。

  一:网页更新

  我们知道一般网页中的信息是不断更新的,这也需要我们定期去抓取这些新的信息,但是我们应该如何理解这个“周期性”,也就是需要多长时间?

  抓取一次页面,其实这段时间也是页面缓存时间。我们不需要在页面缓存时间内再次爬取页面,但是会给服务器带来压力。

  比如我要爬博客园的首页,先清除页面缓存,

  

  从 Last-Modified 到 Expires 可以看到博客园的缓存时间是 2 分钟,我也可以看到当前服务器时间 Date,如果我再

  如果页面被刷新,这里的Date会变成下图中的If-Modified-Since,然后发送给服务器判断浏览器的缓存是否已经过期?

  

  最后服务端找到If-Modified-Since >= Last-Modified的时间,服务端返回304,但是发现这个cookie信息真的是贼多。. .

  

  在实际开发中,如果我们知道网站缓存策略,我们可以让爬虫每2分钟爬一次。当然,这些可以由数据团队配置和维护。

  好吧,让我们用爬虫来模拟它。

  1using System;

2using System.Net;

3

4namespace ConsoleApplication2

5{

6 public class Program

7 {

8 static void Main(string[] args)

9 {

10 DateTime prevDateTime = DateTime.MinValue;

11

12 for (int i = 0; i 0)

23 {

24 request.IfModifiedSince = prevDateTime;

25 }

26

27 request.Timeout = 3000;

28

29 var response = (HttpWebResponse)request.GetResponse();

30

31 var code = response.StatusCode;

32

33 //如果服务器返回状态是200,则认为网页已更新,记得当时的服务器时间

34 if (code == HttpStatusCode.OK)

35 {

36 prevDateTime = Convert.ToDateTime(response.Headers[HttpResponseHeader.Date]);

37 }

38

39 Console.WriteLine("当前服务器的状态码:{0}", code);

40 }

41 catch (WebException ex)

42 {

43 if (ex.Response != null)

44 {

45 var code = (ex.Response as HttpWebResponse).StatusCode;

46

47 Console.WriteLine("当前服务器的状态码:{0}", code);

48 }

49 }

50 }

51 }

52 }

53}

54

  

  2:网络编码的问题

  有时候我们已经抓取了网页,再去解析的时候,tmd全是乱码,真是操蛋,比如下面这样,

  

  或许我们依稀记得html的meta中有一个叫charset的属性,里面记录了编码方式,另外一个关键点是

  编码方式也记录在属性response.CharacterSet中,我们再试一次。

  

  妈的,还是乱码,好痛。这个时候需要去官网看看http头信息中在交互什么。为什么浏览器可以正常显示?

  如果爬行动物爬过来,它就行不通了。

  

  查看http头信息,我们终于知道浏览器说我可以解析gzip、deflate、sdch这三种压缩方式。服务器发送gzip压缩,所以这里是

  我们还应该了解常见的 Web 性能优化。

  1using System;

2using System.Collections.Generic;

3using System.Linq;

4using System.Text;

5using System.Threading;

6using HtmlAgilityPack;

7using System.Text.RegularExpressions;

8using System.Net;

9using System.IO;

10using System.IO.Compression;

11

12namespace ConsoleApplication2

13{

14 public class Program

15 {

16 static void Main(string[] args)

17 {

18 //var currentUrl = "http://www.mm5mm.com/";

19

20 var currentUrl = "http://www.sohu.com/";

21

22 var request = WebRequest.Create(currentUrl) as HttpWebRequest;

23

24 var response = request.GetResponse() as HttpWebResponse;

25

26 var encode = string.Empty;

27

28 if (response.CharacterSet == "ISO-8859-1")

29 encode = "gb2312";

30 else

31 encode = response.CharacterSet;

32

33 Stream stream;

34

35 if (response.ContentEncoding.ToLower() == "gzip")

36 {

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

38 }

39 else

40 {

41 stream = response.GetResponseStream();

42 }

43

44 var sr = new StreamReader(stream, Encoding.GetEncoding(encode));

45

46 var html = sr.ReadToEnd();

47 }

48 }

49}

50

  

  三:网页分析

  现在网页经过一番努力已经得到了,接下来就是解析它了。当然,正则匹配是一个很好的方法。毕竟工作量还是比较大的,业界可能也会尊重。

  HtmlAgilityPack,一个解析工具,可以将Html解析成XML,然后使用XPath提取指定的内容,极大的提高了开发速度,提升了性能。

  还不错,毕竟敏捷也意味着敏捷。关于XPath的内容,这两张W3CSchool的图大家看懂就OK了。

  

  1using System;

2using System.Collections.Generic;

3using System.Linq;

4using System.Text;

5using System.Threading;

6using HtmlAgilityPack;

7using System.Text.RegularExpressions;

8using System.Net;

9using System.IO;

10using System.IO.Compression;

11

12namespace ConsoleApplication2

13{

14 public class Program

15 {

16 static void Main(string[] args)

17 {

18 //var currentUrl = "http://www.mm5mm.com/";

19

20 var currentUrl = "http://www.sohu.com/";

21

22 var request = WebRequest.Create(currentUrl) as HttpWebRequest;

23

24 var response = request.GetResponse() as HttpWebResponse;

25

26 var encode = string.Empty;

27

28 if (response.CharacterSet == "ISO-8859-1")

29 encode = "gb2312";

30 else

31 encode = response.CharacterSet;

32

33 Stream stream;

34

35 if (response.ContentEncoding.ToLower() == "gzip")

36 {

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

38 }

39 else

40 {

41 stream = response.GetResponseStream();

42 }

43

44 var sr = new StreamReader(stream, Encoding.GetEncoding(encode));

45

46 var html = sr.ReadToEnd();

47

48 sr.Close();

49

50 HtmlDocument document = new HtmlDocument();

51

52 document.LoadHtml(html);

53

54 //提取title

55 var title = document.DocumentNode.SelectSingleNode("//title").InnerText;

56

57 //提取keywords

58 var keywords = document.DocumentNode.SelectSingleNode("//meta[@name='Keywords']").Attributes["content"].Value;

59 }

60 }

61}

62

  1 ![](http://img.5iqiqu.com/images1/33/337f037223e08ed0201a22fd4cc3440d.png)

2

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线