Spiderman源码分析(一)加载和初始化

           Spiderman是一款纯Java的网络爬虫开源软件,其以微内核,插件化带来的良好扩展性和维护性而著称,从这篇文章开始,我们将逐步对其源码进行分析,如有理解不到位之处,还望大家之处,本人在此现行谢过。本节就来看看spiderman的加载和初始化。

           在谈加载和初始化之前,有必要对spiderman的几个核心类的组织和分工做个简单的说明,这个有利于后续内容的理解,贯穿爬取这条主线的有如下几个类:Spiderman,Spider,Task,Site,其它辅助性的功能类在讲到时再介绍。Spiderman,是爬虫的入口类,也是主调度类,主要包含两类信息:网站信息(待爬站点列表),调度控制信息。

Spider是具体的一个爬虫(负责一个具体的爬取任务(Task)),一个Task包含对一个具体页面Target的封装,Site对应一个具体的要爬取的站点,这个站点可能包含多个要爬取的目标(Target)。

          要想启动一次爬取任务,需要做两部分工作:一,按照给定的格式填写相应网站的配置文件即:site.xml,二:编写客户端代码,例如:

		//启动爬虫
		spiderman.init(listener)//初始化
			.startup();//启动

这里的spiderman就是一个Spiderman的实例,listener就是一个重写了SpiderListenerAdaptor的客户自定义的监听类,这个监听类的接口如下:

public class SpiderListenerAdaptor implements SpiderListener{
	public void onDigUrls(Thread thread, Task task, String fieldName, Collection<String> urls) {}
	public void onFetch(Thread thread, Task task, FetchResult result) {}
	public void onNewUrls(Thread thread, Task task, Collection<String> newUrls) {}
	public void onDupRemoval(Thread currentThread, Task task, Collection<Task> validTasks) {}
	public void onTaskSort(Thread currentThread, Task task, Collection<Task> afterSortTasks) {}
	public void onNewTasks(Thread thread, Task task, Collection<Task> newTasks) {}
	public void onTargetPage(Thread thread, Task task, Page page) {}
	public void onParse(Thread thread, Task task, List<Map<String, Object>> models) {}
	public void onPojo(Thread thread, Task task, List<Object> pojos) {}
	public void onInfo(Thread thread, Task task, String info) {}
	public void onError(Thread thread, Task task, String err, Throwable e) {e.printStackTrace();}
	<span style="color:#ff6666;">public void onAfterScheduleCancel() {}
	public void onBeforeEveryScheduleExecute(Date theLastTimeScheduledAt){}
	public void onBeforeShutdown() {}
	public void onAfterShutdown() {}
	public void onBeforeShutdown(Site site) {}
	public void onAfterShutdown(Site site) {}
</span>    public void onParseField(Thread thread, Task task, Object selector, String field, Object value) {}
    public void onParseOne(Thread thread, Task task, int size, int index, Map<String, Object> model) {}
}

从接口列表,我们可以看出,用户可以重写这些接口来实现自己的业务逻辑,而spiderman会在相应的事件发生时调用这些接口,将具体的信息传递给客户端(其实就是观察者模式的应用)。这些不是我们要讲的重点,本节我们要讲的是init函数,即:加载和初始化,下面我们来看看这个函数都做了哪些工作:

public Spiderman init(){
		if (this.listener == null)
			this.listener = new SpiderListenerAdaptor();
		isShutdownNow = false;
		sites = null;
		pool = null;
		try {
			<span style="color:#ff6666;">loadPlugins();</span>
		<span style="color:#ff6666;">	initSites();
			initPool();
</span>		} catch (Throwable e){
			e.printStackTrace();
			listener.onInfo(Thread.currentThread(),null, "Spiderman init error.");
			listener.onError(Thread.currentThread(), null, "Spiderman init error.", e);
		}
		return this;
	}
	

很明显:这个函数主要做了三个工作:加载插件,初始化sites和初始化pool,下面分别来分析:

加载插件:

private void loadPlugins() throws Exception{
		File siteFolder = new File(Settings.website_xml_folder());
		if (!siteFolder.exists())
			throw new Exception("can not found WebSites folder -> " + siteFolder.getAbsolutePath());
		
		if (!siteFolder.isDirectory())
			throw new Exception("WebSites -> " + siteFolder.getAbsolutePath() + " must be folder !");
		
		File[] files &
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值