用C#2.0实现网络蜘蛛(WebSpider)
2009-05-29 08:31:25 来源:WEB开发网各位读者可以看看,上面的代码是不是要比直接使用Thread类更方便、直观、易用,还有些面向对象的感觉!
五、用多线程下载网络资源
一般来说,网络蜘蛛都是使用多线程来下载网络资源的。至于如何使用多线程来下载,各个版本的网络蜘蛛不尽相同。为了方便和容易理解,本文所讨论的网络蜘蛛采用了每一个线程负责将网络资源下载到一个属于自己的目录中,也就是说,每一个线程对应一个目录。而在当前目录中下载的网络资源达到一定的数目后(如5000),这个线程就会再建立一个新目录,并从0开始计数继续下载网络资源。在本节中将介绍一个用于下载网络资源的线程类DownLoadThread。这个类的主要功能就是从下载队列中获得一定数量的URL,并进行下载和分析。在DownLoadThread类中涉及到很多其他重要的类,这些类将在后面的部分介绍。在这里我们先看一下DownLoadThread类的实现代码。
DownLoadThread类的代码
class DownLoadThread : MyThread
{
// ParseResource类用于下载和分析网络资源
private ParseResource pr = new ParseResource();
private int currentCount = 0; // 当前下载目录中的网页数
// 用于向每个线程目录中的index.txt中写当前目录的URL
private FileIO fileIO = new FileIO();
private string path; // 当前的下载目录(后面带“\")
private string[] patterns; // 线程不下载符合patterns中的正则表达式的URL
public bool stop = false; // stop为true,线程退出
public int threadID; // 当前线程的threadID,用于区分其他的线程
public DownLoadThread(string[] patterns)
{
pr.findUrl += findUrl; // 为findUrl事件赋一个方法
this.patterns = patterns;
}
// 这是一个事件方法,每获得一个URL时发生
private void findUrl(string url)
{
Common.addUrl(url); // 将获得的URL加到下载队列中
}
private void openFile() // 打开下载目录中的index.txt文件
{
fileIO.CloseWriteFile();
fileIO.OpenWriteFile(path + Common.indexFile);
}
public override void run() // 线程运行方法
{
LinkedList urls = new LinkedList();
path = Common.getDir(); // 获得下载目录
openFile();
while (!stop)
{
// 当下载队列中没有URL时,进行循环等待
while (!stop && urls.Count == 0)
{
Common.getUrls(urls, 20); // 从下载队列中获得20个url
if (urls.Count == 0) // 如果未获得url
{
// 通知系统当前线程已处于等待状态,
// 如果所有的线程都处于等待状态,
// 说明所有的网络资源都被下载完了
Common.threadWait(threadID);
sleep(5000); // 当前线程休眠5秒
}
}
StringBuilder sb = new StringBuilder();
foreach (string url in urls) // 循环对这20个url进行循环下载分析
{
if (stop) break;
// 如果当前下载目录的资源文件数大于等于最大文件数目时,
// 建立一个新目录,并继续下载
if (currentCount >= Common.maxCount)
{
path = Common.getDir();
openFile();
currentCount = 0; // 目录
}
// 每个下载资源文件名使用5位的顺序号保存(没有扩展名),
// 如00001、00002。下面的语句是格式化文件名
string s = string.Format("{0:D5}", currentCount + 1);
sb.Remove(0, sb.Length);
sb.Append(s);
sb.Append(":");
sb.Append(url);
try
{
// 下载和分析当前的url
pr.parse(url, path + s, patterns);
Common.Count++;
// 将当前的url写入index.txt
fileIO.WriteLine(sb.ToString());
currentCount++;
}
catch (Exception e)
{
}
}
urls.Clear();
}
}
}
}
更多精彩
赞助商链接