C# 网络爬虫整理
一、前言
在学了C#的网络爬虫之后,深感C#的强大,和爬虫的有趣,在这里将自己的心得体会记下来,以便日后的学习和回顾。这里有两个程序,首先是一个简单的抓取网页程序,将网页抓取下来之后用正则表达式进行解析,从而得到相应的信息。
二、C#网页爬虫
这里有几个要点:
第一:抓取的源
当我们想抓网页,首先就要知道该网页的具体内容,包含的主要信息,之后我们对信息进行处理,可以确定我们要抓取的网页数量,有两种抓取方法,一种是深度优先,一种是广度优先,最终抓取出所有自己想要的网页。
第二,对源的处理
我们知道我们抓取的是整个网页,有很多信息是我们不需要的,因此有两种处理方法,一种是用正则表达式来处理,另外一种是对DOM(Document Object Model)结构的数据用XPath函数来处理.
第三:处理过程中我们要用到线程
也就是异步任务,因此我们需要对其进行学习,理解async和await这一对孪生兄弟的用法。
1 a) 只有在async方法里面才能使用await操作符; 2 b) await操作符是针对Task对象的; 3 c) 当方法A调用方法B,方法B方法体内又通过await调用方法C时,如果方法C内部有异步操作,则方法B会等待异步操作执行完,才往下执行;但方法A可以继续往下执行,不用再等待B方法执行完。


1 static void Main(string[] args)
2
3 {
4
5 Test();
6
7 Console.WriteLine("Test End!");
8
9 Console.ReadLine();
10
11 }
12
13 static async void Test()
14
15 {
16
17 await Test1();
18
19 Console.WriteLine("Test1 End!");
20
21 }
22
23 static Task Test1()
24
25 {
26
27 Thread.Sleep(1000);
28
29 Console.WriteLine("create task in test1");
30
31 return Task.Run(() =>
32
33 {
34
35 Thread.Sleep(3000);
36
37 Console.WriteLine("Test1");
38
39 });
40
41 }
相当于代码:


1 static void Main(string[] args)
2
3 {
4
5 Test();
6
7 Console.WriteLine("Test End!");
8
9 Console.ReadLine();
10
11 }
12
13 static void Test()
14
15 {
16
17 var test1=Test1();
18
19 Task.Run(() =>
20
21 {
22
23 test1.Wait();
24
25 Console.WriteLine("Test1 End!");
26
27 });
28
29 }
30
31 static Task Test1()
32
33 {
34
35 Thread.Sleep(1000);
36
37 Console.WriteLine("create task in test1");
38
39 return Task.Run(() =>
40
41 {
42
43 Thread.Sleep(3000);
44
45 Console.WriteLine("Test1");
46
47 });
48
49 }
第四:在C#中大量的出现lambda表达式,我们要对其有深刻的理解和认识。
比如:
1 cityCrawler.OnStart += (s, e) => 2 { 3 Console.WriteLine("爬虫开始抓取地址:" + e.Uri.ToString()); 4 };
我们只有深刻的认识了lambda表达式,才能更好的使用和理解它。
第五:
我们的爬虫是怎么伪造浏览器来进行抓包的,如果大量的抓包会被服务器警觉,我们要采用代理来解决这一问题。
第六:
对EventHandler的认识,它的构造有两个参数,一个是当前的上下文,一个是具体的对象(这个对象是我们自己创建的,在该委托的模板中进行传递)。
第七:并发处理。
1 Parallel.For(0, 2, (i) => 2 { 3 var hotel = hotelList[i]; 4 hotelCrawler.Start(hotel.Uri); 5 });
而For函数的定义如下:


1 // 摘要:
2
3 // 执行 for(在 Visual Basic 中为 For)循环,其中可能会并行运行迭代。
4
5 //
6
7 // 参数:
8
9 // fromInclusive:
10
11 // 开始索引(含)。
12
13 //
14
15 // toExclusive:
16
17 // 结束索引(不含)。
18