如何用c#语言构造蜘蛛程式_c#应用

2008-02-23 05:44:33来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

  "蜘蛛"(Spider)是Internet上一种很有用的程式,搜索引擎利用蜘蛛程式将Web页面收集到数据库,企业利用蜘蛛程式监控竞争对手的网站并跟踪变动,个人用户用蜘蛛程式下载Web页面以便脱机使用,研发者利用蜘蛛程式扫描自己的Web检查无效的链接……对于不同的用户,蜘蛛程式有不同的用途。那么,蜘蛛程式到底是怎样工作的呢?

  蜘蛛是一种半自动的程式,就象现实当中的蜘蛛在他的Web(蜘蛛网)上旅行相同,蜘蛛程式也按照类似的方式在Web链接织成的网上旅行。蜘蛛程式之所以是半自动的,是因为他总是需要一个初始链接(出发点),但此后的运行情况就要由他自己决定了,蜘蛛程式会扫描起始页面包含的链接,然后访问这些链接指向的页面,再分析和追踪那些页面包含的链接。从理论上看,最终蜘蛛程式会访问到Internet上的每一个页面,因为Internet上几乎每一个页面总是被其他或多或少的页面引用。

  本文介绍如何用C#语言构造一个蜘蛛程式,他能够把整个网站的内容下载到某个指定的目录,程式的运行界面如图一。您能够方便地利用本文提供的几个核心类构造出自己的蜘蛛程式。

图1


  C#特别适合于构造蜘蛛程式,这是因为他已内置了HTTP访问和多线程的能力,而这两种能力对于蜘蛛程式来说都是很关键的。下面是构造一个蜘蛛程式要解决的关键问题:

  ⑴ HTML分析:需要某种HTML解析器来分析蜘蛛程式碰到的每一个页面。

  ⑵ 页面处理:需要处理每一个下载得到的页面。下载得到的内容可能要保存到磁盘,或进一步分析处理。

  ⑶ 多线程:只有拥有多线程能力,蜘蛛程式才能真正做到高效。

  ⑷ 确定何时完成:不要小看这个问题,确定任务是否已完成并不简单,尤其是在多线程环境下。

  一、HTML解析

  C#语言本身不包含解析HTML的能力,但支持XML解析;但是,XML有着严格的语法,为XML设计的解析器对HTML来说根本没用,因为HTML的语法要宽松得多。为此,我们需要自己设计一个HTML解析器。本文提供的解析器是高度单独的,您能够方便地将他用于其他用C#处理HTML的场合。

  本文提供的HTML解析器由ParseHTML类实现,使用很方便:首先创建该类的一个实例,然后将他的Source属性配置为要解析的HTML文档:

ParseHTML parse = new ParseHTML();
parse.Source = "<p>Hello World</p>";


  接下来就能够利用循环来检查HTML文档包含的任何文本和标记。通常,检查过程能够从一个测试Eof方法的while循环开始:

while(!parse.Eof())
{
char ch = parse.Parse();


  Parse方法将返回HTML文档包含的字符--他返回的内容只包含那些非HTML标记的字符,假如碰到了HTML标记,Parse方法将返回0值,表示现在碰到了一个HTML标记。碰到一个标记之后,我们能够用GetTag()方法来处理他。

if(ch==0)
{
HTMLTag tag = parse.GetTag();
}


  一般地,蜘蛛程式最重要的任务之一就是找出各个HREF属性,这能够借助C#的索引功能完成。例如,下面的代码将提取出HREF属性的值(假如存在的话)。

Attribute href = tag["HREF"];
string link = href.Value;


  获得Attribute对象之后,通过Attribute.Value能够得到该属性的值。

二、处理HTML页面

  下面来看看如何处理HTML页面。首先要做的当然是下载HTML页面,这能够通过C#提供的HttpWebRequest类实现:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(m_uri);
response = request.GetResponse();
stream = response.GetResponseStream();


  接下来我们就从request创建一个stream流。在执行其他处理之前,我们要先确定该文档是二进制文档还是文本文档,不同的文档类型处理方式也不同。下面的代码确定该文档是否为二进制文档。

if( !response.ContentType.ToLower().StartsWith("text/") )
{
SaveBinaryFile(response);
return null;
}
string buffer = "",line;


  假如该文档不是文本文档,我们将他作为二进制文档读入。假如是文本文档,首先从stream创建一个StreamReader,然后将文本文档的内容一行一行加入缓冲区。

reader = new StreamReader(stream);
while( (line = reader.ReadLine())!=null )
{
buffer =line "\r\n";
}


  装入整个文档之后,接着就要把他保存为文本文档。

SaveTextFile(buffer);


  下面来看看这两类不同文档的存储方式。

  二进制文档的内容类型声明不以"text/"开头,蜘蛛程式直接把二进制文档保存到磁盘,不必进行额外的处理,这是因为二进制文档不包含HTML,因此也不会再有需要蜘蛛程式处理的HTML链接。下面是写入二进制文档的步骤。

  首先准备一个缓冲区临时地保存二进制文档的内容。 byte []buffer = new byte[1024];


  接下来要确定文档保存到本地的路径和名称。假如要把一个myhost.com网站的内容下载到本地的c:\test文档夹,二进制文档的网上路径和名称是http://myhost.com/images/logo.gif,则本地路径和名称应当是c:\test\images\logo.gif。和此同时,我们还要确保c:\test目录下已创建了images子目录。这部分任务由convertFilename方法完成。

string filename = convertFilename( response.ResponseUri );


  convertFilename方法分离HTTP地址,创建相应的目录结构。确定了输出文档的名字和路径之后就能够打开读取Web页面的输入流、写入本地文档的输出流。

Stream outStream = File.Create( filename );
Stream inStream = response.GetResponseStream();


  接下来就能够读取Web文档的内容并写入到本地文档,这能够通过一个循环方便地完成。

int l;
do
{
l = inStream.Read(buffer,0,
buffer.Length);
if(l>0)

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇: 如何在c#中使用win32和其他库_c#应用

下一篇: 在c#中使用属性控件添加属性窗口_c#应用