65.9K
CodeProject 正在变化。 阅读更多。
Home

简单的爬虫类

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.45/5 (5投票s)

2009 年 12 月 26 日

CPOL

2分钟阅读

viewsIcon

32308

downloadIcon

2351

一个多线程爬虫,可以下载页面并将它们本地保存,同时保留站点树结构。

引言

“MyCrawler”是一个用 C# 编写的类,它的功能是“爬虫”,即一个程序,给定一个根 URL(或多个根),它会爬取网站并下载页面及其中的任何链接。它使用多线程、过滤器和深度来进行精确和快速的下载。

背景

这个类是作为一个更大的数据挖掘项目的一部分编写的。

除了主类“CrawlerGeneric”之外,还有一些辅助类

  • Network - 继承了“WebClient”类,并重载了“downloadstring”方法以执行更具体的任务。
  • IO - 负责本地保存页面。
  • MyRegex - 包含各种字符串操作方法的辅助类。
  • Compresser - 由网络类用于处理压缩数据。

使用代码

要使用爬虫,我们需要首先创建一个“CrawlerGeneric”的实例;但是,建议将其用作基类,并创建您自己的类来实现“ExtractLinks”和“Filter”方法(如下所述)。

public class MyCrawler : CrawlerGeneric
{
    protected override List<string> ExtractLinks(string pageData,string url)
    {
        List<string> links = BuiltInExtractLinks(pageData,url);
        //Do some sort of logic here
        return links;
    }

    protected override bool Filter(string url)
    {
        url = url.ToLower();
        if (url.Contains("search?") && url.Contains("&start="))
            return false;
        return true;
    }
}

ExtractLinks”方法允许您获取已下载页面的数据及其 URL,并从链接列表中添加或删除链接。 链接列表保存了从页面中提取的 URL 列表。 BuiltInExtractLinks是一个私有函数,它提取页面中“href”属性内的所有 URL。

Filter”方法检查链接列表中的每个 URL;只有返回false的 URL 才会被下载。

创建 MyCrawler 的实例

编写我们自己的类后,我们实例化它并设置其属性。

MyCrawler crawler = new MyCrawler();
crawler.CrawlerDepth = 2;
crawler.NumOfConcurrentThreads = 10;
crawler.OutputDirectory = "c:\\test";
crawler.Roots = new string[] { @"http://www.google.co.il/search?" & _ 
   "hl=en&lr=&rlz=1G1GGLQ_IWIL297&q=codeproject&start=0&sa=N" };
crawler.AllowCompression = false;

//Time for thread to sleep when there is no url's to handle
crawler.ThreadIdleTime = 500;
//Time for thread to sleep after downloading a page
crawler.ThreadSleepTime = 500; 

AllowComperssion”属性允许我们选择是否可以使用“gzip/deflate”压缩器下载数据。 在本例中,我将其设置为false,因为我正在从 Google 下载页面,并且我注意到从 Google 发送的压缩数据是使用 zip 方法压缩的,而不是 gzip,因此会收到异常“GZip 标头中的幻数不正确。 请确保您传入的是 GZip 流 ”。

连接事件

该类可以被任何 UI 应用程序使用。 因此,它使用事件来警报更改。 此外,它还有一个事件来警报下载过程何时结束。

.
.
.

crawler.DataCanged += new 
  EventHandler<Analayza.Crawler.Events.MyEventArgs>(crawler_DataCanged); 

crawler.Finished += new EventHandler<Analayza.Crawler.
   Events.FinishedDownloadingEventArgs>(crawler_Finished);

//Check connection to internet
if (!crawler.IsConnectedToInternet())
{
    Console.WriteLine("Not connected to the internet");
    return;
}

//Start crawling
crawler.Go();

//dont exit until crawler has finished
while (fin == false)
{
    System.Threading.Thread.Sleep(1000);
}

static void crawler_Finished(object sender, 
  Analayza.Crawler.Events.FinishedDownloadingEventArgs e)
{
    fin = true;
}

static void crawler_DataCanged(object sender, 
  Analayza.Crawler.Events.MyEventArgs e)
{
    Console.WriteLine(e.Message);
}

关注点

因为爬虫下载站点树并使用 URL 路径作为文件名,所以可能存在本地磁盘上的整个路径超过 260 个字符的情况,这是 Windows 文件系统 限制 的路径长度。 因此,爬虫使用一种名为 MyRegex.ToValidWindowsPath 的方法将 URL 转换为有效的 Windows 路径(排除非法字符),如果需要,则截断名称(限制为 250,以防万一...)。

public static string ToValidWindowsPath(string directory, string file)
{
    string newfile = ToValidWindowsFileName(file);
    string fullPath = directory + newfile;

    if (fullPath.Length > 250)
    {
        if (directory.Length > 230)
            return "";

        int fileNewLength = 248 - directory.Length; //minimum 18 characters

        if (newfile.Length > 10)
            newfile = newfile.Substring(0, 10);

        Random rand = new Random();
        fullPath = directory + newfile + rand.Next(0, 400000).ToString();
        return fullPath;
    }
    return fullPath;
}

感谢..

感谢 gizmo ... :)

© . All rights reserved.