Heritrix源码分析(十一) Heritrix中的URL--CandidateURI和CrawlURI以及如何增加自己的属性(转)
本博客属原创文章,欢迎转载!转载请务必注明出处:http://guoyunsky.iteye.com/blog/649889
本博客已迁移到本人独立博客: http://www.yun5u.com/
欢迎加入Heritrix群(QQ):109148319,10447185 , Lucene/Solr群(QQ) : 118972724
Url是爬虫的核心,因为爬虫就是依赖URL一层一层的抓取下去,最后完成整个抓取。Heritrix中的URL比较特殊,有以下继承关系(由于不对继承关系作介绍,所以这里就不画图了):
1)org.archive.crawler.datamodel.CrawlURI——>CandidateURI
2)org.archive.net.UURI——>org.archive.net.LaxURI
——>org.apache.commons.httpclient.URI——>java.net.URL
前面说过CrawlURI和CandidateURI的区别在于CrawlURI是由通过了调度器(Frontier)的CandidateURI转换而来的。下面就先介绍CnadidateURI(主要介绍相关属性):
- public static final int HIGH = 1; //调度器调度等级:高
- public static final int HIGHEST = 0; //调度器调度等级:最高
- public static final int MEDIUM = 2; //调度器调度等级:中
- public static final int NORMAL = 3; //调度器调度等级:普通
- //URL字符串
- private String cachedCandidateURIString = null;
- //队列Key,不同队列有不同的classKey.其中相同classKey的CandidateURI则属于相同的队列
- private String classKey;
- //是否强制访问,强制访问的话会重复抓取
- private boolean forceRevisit = false;
- // 是不是种子
- private boolean isSeed = false;
- /**
- * 灵活的属性列表,Heritrix在运行过程中需要保存不固定的属性和属性值,
- *同时扩展Heritrix属性 也可以放在里面。不过需要特殊处理,等下单独介绍
- */
- private transient AList alist;
- /**
- * 该值代表当前CandidateURI是如何从种子那里生成的,有如下生成方式:
- * P:预先处理URL,一般是DNS,如DNS:www.baidu.com
- * R:重定向URL
- * E:嵌入式URL,如Frame、src等
- * X:特殊嵌入式URL,如JS中的URL
- * L:一般意义上的URL,如<a href="www.baidu.com">
- * 该属性除了可以记录从种子那来源方式的话同时还可以记录深度,因为
- * 该值是一层一层传递,每传递一层则增加一个以上字符.如此通过长度
- * 可以判断当前URL属于种子的第几层从而做到控制抓取深度, 如果当
- * 前CandidateURI是种子,则该值为null
- */
- private String pathFromSeed;
- private int schedulingDirective = NORMAL; // 调度等级,默认为普通
- private transient UURI uuri; //URL
- private transient UURI via; //来源URL
- private CharSequence viaContext;//来源URL内容
下面再介绍一下CrawlURI相关属性,前面说过CrawlURI和CandidateURI最大区别就是CrawlURI通过了调度器,这也就意味着CrawlURI会进入队列抓取,如此CrawlURI就会相比CandidateURI对很多属性来记录抓取情况,如处理器,下面请看代码以及注释:
- //数组用户保存alist成员的key,使得URI处理期间可以持久化访问.这个list中的所有的key在传递下去的处理链 后面都不会被清理掉
- private static final List<Object> alistPersistentMember = new CopyOnWriteArrayList<Object>(
- new String[] { A_CREDENTIAL_AVATARS_KEY });
- // 一个CrawlURI所允许的最大外链接数(就是该CrawlURI本身网页里所包含的链接数),默认为6000
- public static final int MAX_OUTLINKS = Integer.parseInt(System.getProperty(
- CrawlURI.class.getName() + ".maxOutLinks", "6000"));
- // 放弃的外链接个数(当一个URL抽取出来的链接数超过MAX_OUTLINKS时就放弃,然后本变量累加)
- transient private int discardedOutlinks = 0;
- public static final int UNCALCULATED = -1; //网页内容长度,默认值
- private String cachedCrawlURIString = null; //缓存的URL
- private byte[] contentDigest = null; //网页内容指纹,对内容进行MD5值,该对象可以用于对比该URL是否有更新
- private String contentDigestScheme = null; // 记录网页内容所采用算法,从配置文件里配置
- private long contentLength = UNCALCULATED; //相应内容长度
- private long contentSize = UNCALCULATED; //网页内容大小
- private String contentType = null; //网页内容类型
- private int deferrals = 0; //从先决条件URL延迟数
- private int fetchAttempts = 0; // 获取URL的个数
- private int fetchStatus = 0; //获取URL内容状态,默认为0,表示没有尝试过
- transient Object holder; // 所属的队列(WorkQueue)
- int holderCost = UNCALCULATED; //成本
- transient Object holderKey; //所属队列的classkey
- private transient HttpRecorder httpRecorder = null; //记录网页内容
- transient private boolean linkExtractorFinished = false; //抽取是否成功,如果成功则该URL不会再被抽取
- transient private Processor nextProcessor; // 下一个处理器
- transient private ProcessorChain nextProcessorChain;// 下一条处理链
- protected long ordinal; //Crawl自增数目,用于广度优先抓取
- transient Collection<Object> outLinks = new HashSet<Object>(); //该URL抽取到的所有的连接
- private boolean post = false; // 提交url是否post,对应HttpClient的HttpPost
- private boolean prerequisite = false; //是否有优先URL要处理,一般是DNS
- transient private int threadNumber; //线程个数
- private String userAgent = null; //用户代理,表名当前身份
- @Deprecated
- private int embedHopCount = UNCALCULATED;
- @Deprecated
- private int linkHopCount = UNCALCULATED; // 跃点数,表示来自种子的第几层,该值可以控制抓取深度
同时很多人在使用Heritrix的时候需要增加自己的属性,我之前也有这样的需求。不过那时是直接修改源代码增加几个属性,然后在抽取的时候将新的属性赋给抽取出来的URL即可。后来才发现完全没有这个必要,Heritrix已经提供了这样一个功能,可以自定义放入各种属性和属性值。同时Heritrix自己在运行过程中也是如此,把一些会动态变化的属性放入其中,如HttpStatus Code。下面就介绍下其相关原理以及如何使用这个功能:
1)原理:
CandidateURI里面有一个属性private transient AList alist;该属性实际上是一个HashTable,其中Key为属性,Value为属性值。如此一致贯穿整个抓取,可以随时动态读写。但由于该属性是transient,也就意味着HashTable里面的值不会被持久化,所以Heritrix在CrawlURI里面引入一个个变量来记录HashTable中需要持久化的Key,也就是我们所要持久化的属性了:private static final List<Object> alistPersistentMember = new CopyOnWriteArrayList<Object>( new String[] { A_CREDENTIAL_AVATARS_KEY });该属性类型为CopyOnWriteArrayList,也就是专门用于复制写的List,里面存放需要持久化的Key。所以当你需要某个HashTable中的某个Key持久化的时候,只需要在该变量里添加即可。
2)使用方法:
1.存放属性和属性值,变量可以按多种类型存放:
- //放入类型为Int的值
- public void putInt(String key, int value) {
- getAList().putInt(key, value);
- }
- //放入类型为Long的属性值
- public void putLong(String key, long value) {
- getAList().putLong(key, value);
- }
- //放入类型为Object的属性值
- public void putObject(String key, Object value) {
- getAList().putObject(key, value);
- }
- //放入类型为String的属性值
- public void putString(String key, String value) {
- getAList().putString(key, value);
- }
2.获得属性和属性值:
- //获得属性的值,该值为Int类型
- public int getInt(String key) {
- return getAList().getInt(key);
- }
- //获得属性的值,该值为Long类型
- public long getLong(String key) {
- return getAList().getLong(key);
- }
- //获得属性的值,该值为Object类型
- public Object getObject(String key) {
- return getAList().getObject(key);
- }
- //获得属性的值,该值为String类型
- public String getString(String key) {
- return getAList().getString(key);
- }
3.查看是否包含某个属性:
- //查看是否包含某个属性
- public boolean containsKey(String key) {
- return getAList().containsKey(key);
- }
4.获得所有的属性:
- //返回所有的属性值
- public Iterator keys() {
- return getAList().getKeys();
- }
5.让某个属性持久化:
- public void makeHeritable(String key) {
- @SuppressWarnings("unchecked")
- List<String> heritableKeys = (List<String>) getObject(A_HERITABLE_KEYS);
- if (heritableKeys == null) {
- heritableKeys = new ArrayList<String>();
- heritableKeys.add(A_HERITABLE_KEYS);
- putObject(A_HERITABLE_KEYS, heritableKeys);
- }
- heritableKeys.add(key);
- }
6.让某个属性不持久化:
- public void makeNonHeritable(String key) {
- List heritableKeys = (List) getObject(A_HERITABLE_KEYS);
- if (heritableKeys == null) {
- return;
- }
- heritableKeys.remove(key);
- if (heritableKeys.size() == 1) {
- // only remaining heritable key is itself; disable completely
- remove(A_HERITABLE_KEYS);
- }
- }
以上6个介绍完全可以让你扩展自己的属性以及让他们持久化,如果还有其他问题,请留言,或者加入群:10447185
Heritrix源码分析(十一) Heritrix中的URL--CandidateURI和CrawlURI以及如何增加自己的属性(转)的更多相关文章
- Heritrix源码分析(九) Heritrix的二次抓取以及如何让Heritrix抓取你不想抓取的URL
本博客属原创文章,欢迎转载!转载请务必注明出处:http://guoyunsky.iteye.com/blog/644396 本博客已迁移到本人独立博客: http://www.yun5u ...
- Heritrix源码分析(十三) Heritrix的控制中心(大脑)CrawlController(二)
本博客属原创文章,欢迎转载!转载请务必注明出处:http://guoyunsky.iteye.com/blog/650744 本博客已迁移到本人独立博客: http://www.yun5u. ...
- Heritrix源码分析(七) Heritrix总体介绍(转)
本博客属原创文章,欢迎转载!转载请务必注明出处:http://guoyunsky.iteye.com/blog/642794 本博客已迁移到本人独立博客: http://www.yun ...
- Heritrix源码分析(十) Heritrix中的Http Status Code(Http状态码)(转)
本博客属原创文章,欢迎转载!转载请务必注明出处:http://guoyunsky.iteye.com/blog/649737 本博客已迁移到本人独立博客: http://www.yun5u ...
- Heritrix源码分析(六) Heritrix的文件结构分析(转)
本博客属原创文章,欢迎转载!转载请务必注明出处:http://guoyunsky.iteye.com/blog/642618 本博客已迁移到本人独立博客: http://www.yun5u. ...
- Heritrix源码分析(十四) 如何让Heritrix不间断的抓取(转)
欢迎加入Heritrix群(QQ):109148319,10447185 , Lucene/Solr群(QQ) : 118972724 本博客已迁移到本人独立博客: http://www.yun5u ...
- Heritrix源码分析(十四)
近段时间在搞定Lucene的一些问题,所以Heritrix源码分析暂时告一段落.今天下午在群里有同学提到了Heritrix异常终止的问题以及让Heritrix不停的抓取(就是抓完一遍后载入种子继续抓取 ...
- angular源码分析:angular中脏活累活的承担者之$interpolate
一.首先抛出两个问题 问题一:在angular中我们绑定数据最基本的方式是用两个大括号将$scope的变量包裹起来,那么如果想将大括号换成其他什么符号,比如换成[{与}],可不可以呢,如果可以在哪里配 ...
- angular源码分析:angular中入境检察官$sce
一.ng-bing-html指令问题 需求:我需要将一个变量$scope.x = '<a href="http://www.cnblogs.com/web2-developer/&qu ...
随机推荐
- (转)android屏幕适配
声明:eoe文章著作权属于作者,受法律保护,转载时请务必以超链接形式附带如下信息 原文作者: zhuangyujia 原文地址: http://my.eoe.cn/zhuangyujia/archiv ...
- Useful for Android the development engineer from Github
Original:http://sysmagazine.com/posts/216591/ Many plowing on open space Github, I found assemblage ...
- 创建DB2数据库时报错--SQL1052N 数据库路径不存在(Windows)(转载)
用DB2 v9.7新建数据库的时候,默认路径为:D:\ 把缺省路径“写的是D:\XXX(此目录存在),新建时提示如下:SQL1052N 数据库路径 "D:\XXX" 不存在.如下: ...
- ADs系列之通用数据解析服务GAS(即将开源)
面对成百上千的生产系统用户操作数据接入落地,你是否厌倦了每次机械编写打包解包的代码?对一次性接入多个数据的时候,还要对不同人联调,费时费力,你是否还会手忙脚乱,忙中不断出错?是否当数据出问题了,用的时 ...
- jdk、apache-ant结合yuicompressor配置的CSS与JS合并压缩工具
前序:网上很多css与js合并打包工具,其中最流行的就是ant结合yui-compressor,鉴于学习与工作需要今天就学习了一下这种方式,供大家学习交流. 步骤:1.安装jdk,并配置其变量环境:有 ...
- Windows Services Windows Services的操作
Windows Services的操作 一.服务的创建: 1.新建项目——Windows服务 2.这是每个人都会犯的错误,新建一个项目后,都会按F5(运行),就会出现如下错误: 3.安装服务有很多种方 ...
- 在Visual C++下搭建OpenGL的开发环境
1.确保你的电脑已经安装了visual c++编译器 如果还没安装的话,这里有个安装包,可以复制链接进行下载:http://pan.baidu.com/s/1bn4XTqn 2.下载GLUT 下载 ...
- Weblogic控制器的部署
WebLogic的安装 一 WebLogic安装 1. 打开WebLogic安装程序:oepe11_wls1031.exe(我们选用的是WebLogic 10.3g).如图1-1所示: 图1-1 ...
- python 内建函数 type() 和 isinstance() 介绍
Python 不支持方法或函数重载, 因此你必须自己保证调用的就是你想要的函数或对象.一个名字里究竟保存的是什么?相当多,尤其是这是一个类型的名字时.确认接收到的类型对象的身份有很多时候都是很有用的. ...
- 9.cadence.封装1[原创]
一.封装中几个重要的概念 软件如下: ①.Regular pad(正规焊盘) 用在:top layer,bottom layer,internal layer(信号层) ②.thermal relie ...