Internet上的一些站点常常存在着镜像网站(mirror),即两个网站的内容一样但网页对应的域名不同。这样会导致对同一份网页爬虫重复抓取多次。为了避免这种情况,对于每一份抓取到的网页,它首先需要进入ContentSeen模块。该模块会判断网页的内容是否和已下载过的某个网页的内容一致,如果一致,则该网页不会再被送去进行下一步的处理。这样的做法能够显著的降低爬虫需要下载的网页数。至于如果判断两个网页的内容是否一致,一般的思路是这样的:并不会去直接比较两个网页的内容,而是将网页的内容经过计算生成FingerPrint(指纹),通常FingerPrint是一个固定长度的字符串,要比网页的正文短很多。如果两个网页的FingerPrint一样,则认为它们内容完全相同。

为了完成这一模块,首先我们需要一个强大的指纹算法,将我们的网页内容计算成指纹存入数据库,下次直接判断指纹在保存前通过指纹的对比即可成功完成去重复操作。

阅读全文 »

Url Filter则是对提取出来的URL再进行一次筛选。不同的应用筛选的标准是不一样的,比如对于baidu/google的搜索,一般不进行筛选,但是对于垂直搜索或者定向抓取的应用,那么它可能只需要满足某个条件的url,比如不需要图片的url,比如只需要某个特定网站的url等等。Url Filter是一个和应用密切相关的模块。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
using System;
using System.Collections.Generic;
using Crawler.Common;

namespace Crawler.Processing
{
public class UrlFilter
{
public static List<Uri> RemoveByRegex(List<Uri> uris, params string[] regexs)
{
var uriList=new List<Uri>(uris);
for (var i = 0; i < uriList.Count; i++)
{
foreach (var r in regexs)
{
if (!RegexHelper.IsMatch(uriList[i].ToString(), r)) continue;
uris.RemoveAt(i);
i--;
}
}
return uriList;
}

public static List<Uri> SelectByRegex(List<Uri> uris, params string[] regexs)
{
var uriList = new List<Uri>();
foreach (var t in uris)
foreach (var r in regexs)
if (RegexHelper.IsMatch(t.ToString(), r))
if(!uriList.Contains(t))
uriList.Add(t);
return uriList;
}

}
}

之前我们已经基于ARSoft.Tools.Net简单实现了DNS解析模块的功能,但是当性能要求升高时,每一次爬取都要进行DNS请求,甚至很有可能一段时间内每次请求的都是相同的地址,频繁的DNS请求就会成为性能瓶颈,所以我们要通过缓存机制将DNS解析结果缓存下来,降低DNS解析操作,提升系统性能。

阅读全文 »

最近因为一个作业需要完成CNKI爬虫,研究爬虫架构的时候发现了这个疑似移植于Python的著名开源爬虫框架Scrapy的ScrapySharp,然而在网上寻找之后只发现了这个F#的Demo,就使用原文中示例的网站写了这个C#版本的代码。

阅读全文 »

在Web应用运行过程中,我们难免会遇到程序运行异常,这个时候我们就应该将异常信息记录下来,以便开发人员和维护人员对异常原因进行还原,对异常原因进行修复。在ASP.NET平台中进行日志记录的组件也有很多,如Log4Net、CommonLogging等,我们这里选用Log4Net进行异常日志的记录。

阅读全文 »

之前的学习中,在对Session校验完成登录验证时,通常使用Filter来处理,方法类似与前文的错误日志过滤,即新建Filter类继承ActionFilterAttribute类,重写OnActionExecuting方法,之后直接在需要验证的Action前加上Filter标记即可。

阅读全文 »