简单的爬虫类






3.45/5 (5投票s)
一个多线程爬虫,可以下载页面并将它们本地保存,同时保留站点树结构。
引言
“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 ... :)