博学而笃志 切问而近思 仁在其中
详情
网络爬虫一
作者:Aliot     发布时间:2017-07-10     评论:0     阅读:1

网络爬虫在信息检索与处理中有很大的作用,是收集网络信息的重要工具。

接下来就介绍一下爬虫的简单实现。

爬虫的工作流程如下


爬虫自指定的URL地址开始下载网络资源,直到该地址和所有子地址的指定资源都下载完毕为止。http://mmm.qqq23.com

下面开始逐步分析爬虫的实现。

 

1. 待下载集合与已下载集合

为了保存需要下载的URL,同时防止重复下载,我们需要分别用了两个集合来存放将要下载的URL和已经下载的URL

因为在保存URL的同时需要保存与URL相关的一些其他信息,如深度,所以这里我采用了Dictionary来存放这些URL

具体类型是Dictionary 其中stringUrl字符串,int是该Url相对于基URL的深度。

每次开始时都检查未下载的集合,如果已经为空,说明已经下载完毕;如果还有URL,那么就取出第一个URL加入到已下载的集合中,并且下载这个URL的资源。

 

2. HTTP请求和响应

C#已经有封装好的HTTP请求和响应的类HttpWebRequestHttpWebResponse,所以实现起来方便不少。

为了提高下载的效率,http://www.qqq100.com 我们可以用多个请求并发的方式同时下载多个URL的资源,一种简单的做法是采用异步请求的方法。

控制并发的数量可以用如下方法实现

 1 private void DispatchWork()

 2 {

 3     if (_stop) //判断是否中止下载

 4     {

 5         return;

 6     }

 7     for (int i = 0; i < _reqCount; i++)

 8     {

 9         if (!_reqsBusy[i]) //判断此编号的工作实例是否空闲

10         {

11             RequestResource(i); //让此工作实例请求资源

12         }

13     }

14 }



由于没有显式开新线程,所以用一个工作实例来表示一个逻辑工作线程

1 private bool[] _reqsBusy = null; //每个元素代表一个工作实例是否正在工作

2 private int _reqCount = 4; //工作实例的数量

 每次一个工作实例完成工作,相应的_reqsBusy就设为false,并调用DispatchWork,那么DispatchWork就能给空闲的实例分配新任务了。

 

 接下来是发送请求


1 private void RequestResource(int index)

 2 {

 3     int depth;

 4     string url = "";

 5     try

 6     {

 7         lock (_locker)

 8         {

 9             if (_urlsUnload.Count <= 0)

10             {

11                 _workingSignals.FinishWorking(index);

12                 return;

13             }

14             _reqsBusy[index] = true;

15             _workingSignals.StartWorking(index);

16             depth = _urlsUnload.First().Value;

17             url = _urlsUnload.First().Key;

18             _urlsLoaded.Add(url, depth);

19             _urlsUnload.Remove(url);

20         }

21                

22         HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);

23         req.Method = _method; //请求方法

24         req.Accept = _accept; //接受的内容

25         req.UserAgent = _userAgent; //用户代理

26         RequestState rs = new RequestState(req, url, depth, index); //回调方法的参数

27         var result = req.BeginGetResponse(new AsyncCallback(ReceivedResource), rs); //异步请求

28         ThreadPool.RegisterWaitForSingleObject(result.AsyncWaitHandle, //注册超时处理方法

29                 TimeoutCallback, rs, _maxTime, true);

30     }

31     catch (WebException we)

32     {

33         MessageBox.Show("RequestResource " + we.Message + url + we.Status);

34     }

35 }

26行的请求的额外信息在异步请求的回调方法作为参数传入,之后还会提到。

27行开始异步请求,这里需要传入一个回调方法作为响应请求时的处理,同时传入回调方法的参数。

28行给该异步请求注册一个超时处理方法TimeoutCallback,最大等待时间是_maxTime,且只处理一次超时,并传入请求的额外信息作为回调方法的参数。

 

未完待续.......



上一篇:Web发展史
下一篇:测试
相关文章
loading......
最新动态
所有评论

loading......

网站声明:
本站部分内容来自网络,如您发现本站内容
侵害到您的利益,请联系本站管理员处理。
联系站长
373515719@qq.com
关于本站:
编程参考手册