Spiderman源码分析(四)Frontier

          这节我们来看看Spiderman中的任务队列,Spiderman中的每个Site爬取相互独立,包括配置以及所有爬取相关模块,当然也包括任务队列和去重DB(JE)。

在每个Site内部有个TaskQueue为本Site的任务队列,这个TaskQueue内部封装了一个JDK提供的优先级队列,PriorityBlockingQueue,前面提到过,这个任务队列的每个元素是一个Task对象,每个Task有一个sort属性,这个代表了本Task的优先级,并且定义了一个比较器对压入队列的Task进行排序,从而实现优先级的功能。

	private PriorityBlockingQueue<Task> queue = new PriorityBlockingQueue<Task>(5000, new Comparator<Task>(){
		public int compare(Task t1, Task t2) {
			if (t1.sort == t2.sort) return 0;
			return t1.sort > t2.sort ? 1 : -1;
		}
	});

       浏览源码会发现,TaskQueue是已经内置好了的,没有提供相关的接口供用户提供自己的关于任务队列的实现,这一点仁者见仁,之智者见智吧,我个人认为,并不是所有的东西都做成可以供扩展的就好,所谓有所变有所不变,对于爬取来讲,一个优先级队列或许已经能够满足大部分爬取情形,优先级高的任务(URL)可以先爬取,这也符合基本的爬取规则。不过Spiderman提供了三个扩展点让用户来对任务队列提供自己的附加功能,分别是:TaskSortPoint,TaskPushPoint和TaskPollPoint,第一个扩展点提供对任务设置优先级的接口,可以在这里根据自己的业务规则设定即将放入队列的Task的优先级,不过当优先级相同时,并不一定是先放入队列的任务先执行,笔者做了个测试,反而是后放入的任务优先执行,这个可能和PriorityBlockingQueue的内部实现有关,有时间再详细研究。第二个Push扩展点用来将任务放入队列,在这里,可以进行一些入队前的处理,例如一些过滤操作,在默认提供的扩展实现中进行了Host过滤,Target和SourceRule过滤(这些在前面第二节中已经分析,这里就不再累述)。TaskPollPoint扩展点负责从任务队列中取出任务,注意这里的实现采用的queue.poll接口,而不是take接口,前者为飞阻塞,后者为阻塞,之所以用非阻塞,在site的主线程中已经看以看到,如果队列为空,则会继续等待设定的时间,如果采用阻塞接口则当前线程会一直阻塞知道队列中加入新的任务,显然非阻塞模式更加高效,阻塞模式略显浪费资源。

					//扩展点:TaskPoll
					Task task = null;
					Collection<TaskPollPoint> taskPollPoints = site.taskPollPointImpls;
					if (taskPollPoints != null && !taskPollPoints.isEmpty()){
						for (Iterator<TaskPollPoint> it = taskPollPoints.iterator(); it.hasNext(); ){
							TaskPollPoint point = it.next();
							task = point.pollTask();
						}
					}
					
					if (task == null){
						long wait = CommonUtil.toSeconds(site.getWaitQueue()).longValue();
//						listener.onInfo(Thread.currentThread(), null, "queue empty wait for -> " + wait + " seconds");
						if (wait > 0) {
							try {
								Thread.sleep(wait * 1000);
							} catch (Exception e){
								
							}
						}
						continue;
					}

细心的读者会发现TaskQueue中的push接口在执行之情还做了最后的过滤,即基于配置文件中定义的队列过滤规则对压入的URL进行过滤,由此可见,Spiderman是竭尽所能满足用户的灵活爬取。
本节就到此,下节来看看Spiderman最大的一个模块Parser。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值