Berkeley DB的使用

最近在思考网络爬虫的增量更新问题,很明显,如果将URL放在unvisitedQueue中和visitedQueue中,而这两个队列仅仅简单的用JAVA提供的容器进行实现,那么由于内存的掉电易失性,再下一次爬爬取时,又是重复的从种子URL集合中取得URL,判断是否访问过,放入unvisitedQueue队列中,其实如果两次爬取的间隔时间不长的话,大量重复的链接被重复判断,效率极低。

如果爬虫想要实现增量更新,那么URL就应该存放在一种快速而持久的数据库中。那么第二次爬取的链接来自于unvisitedQueue中,相当于在第一次爬取的基础上进行更新。如果要判断以前爬取页面的时新性,可以用一个单独的模块,遍历已存储的链接(在每次爬取时,就获得页面时间),进行更新。

Berkeley DB是一种嵌入式的数据库,以键值对的方式进行数据的存储,而且对于数据的读和取非常快,非常满足我们对于URL队列,快速、持久及海量存取的要求。

基于Berkeyley DB的队列实现代码如下所示:

package com.ThemeSearchSpider.container;
import com.sleepycat.bind.serial.SerialBinding;
import com.sleepycat.bind.serial.StoredClassCatalog;
import com.sleepycat.collections.StoredMap;
import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseConfig;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig;
import java.io.*;
import java.util.Iterator;
import java.util.Map.Entry;
/*
 * author:Tammy Pi function:用Berkeley DB模拟队列
 */
public class DBQueue implements Queue{

	private EnvironmentConfig envConfig=null;
	private Environment env=null;
	private Database database=null;
	private Database dbCatalog=null;
	private StoredClassCatalog javaCatalog=null;
	private String dbPath="e:\\BerkeleyDB\\unVisitedQueue\\";
	private final String catalog="java_class_catalog";
	private StoredMap map=null;
	
	//构造函数,初始化
	public DBQueue(){
		
		if(!new File(dbPath).exists())
		{
			new File(dbPath).mkdir();
		}
		
		envConfig=new EnvironmentConfig();
		envConfig.setTransactional(true);
		envConfig.setAllowCreate(true);
		env=new Environment(new File(dbPath),envConfig);
		
		DatabaseConfig databaseConfig1=new DatabaseConfig();
		databaseConfig1.setTransactional(true);
		databaseConfig1.setAllowCreate(true);
		dbCatalog=env.openDatabase(null,catalog,databaseConfig1);
		javaCatalog=new StoredClassCatalog(dbCatalog);
		
		
		DatabaseConfig databaseConfig=new DatabaseConfig();
		databaseConfig.setAllowCreate(true);
		databaseConfig.setTransactional(true);
		database=env.openDatabase(null,"URL",databaseConfig);
		
		SerialBinding keyBinding=new SerialBinding(javaCatalog,String.class);
		SerialBinding valueBinding=new SerialBinding(javaCatalog,String.class);
		map=new StoredMap(database,keyBinding,valueBinding,true);
	}
	//关闭数据库
	public void close(){
		
		if(dbCatalog!=null)
		{
			dbCatalog.close();
		}
		if(database!=null)
		{
			database.close();
		}
		if(env!=null)
		{
			env.close();
		}
	}
	@Override
	public void enQueue(String url) {
	  // TODO Auto-generated method stub
	  //如果不含有,才将url放入队列
	  if(!map.containsKey(url))
	  {
		  map.put(url,url);
	  }
	}
	@Override
	public String deQueue() {
		// TODO Auto-generated method stub
		Iterator iterator=map.entrySet().iterator();
		String url=null;
		while(iterator!=null&&iterator.hasNext())
		{
			Entry<String,String> entry=(Entry<String, String>) iterator.next();
			url=entry.getKey();
		}
		if(url!=null)
		{
			map.remove(url);
		}
		
		return url;
	}
	@Override
	public boolean isEmpty() {
		// TODO Auto-generated method stub
		return map.isEmpty();
	}
	@Override
	public boolean contains(String url) {
		// TODO Auto-generated method stub
		return map.containsKey(url);
	}
	
	//用于测试的主函数
	public static void main(String[] args)
	{
		DBQueue queue=new DBQueue();
		queue.enQueue("http://www.baidu.com");
		queue.enQueue("http://www.sina.com");
		System.out.println(queue.contains("http://www.baidu1.com"));
		System.out.println(queue.contains("http://www.baidu.com"));
		while(!queue.isEmpty())
		{
			System.out.println(queue.deQueue());
		}
        queue.close();
	}
}

Berkeley DB的下载链接:http://download.csdn.net/detail/rongyongfeikai2/4317973

首先写一个Queue的接口,定义好应该包括的方法;再用DBQueue实现Queue接口;再用unVisitedQueue和visitedQueue继承至DBQueue,这两个类没有多的代码,仅仅是数据库名字不同。这样共同构成了com.ThemeSearchSpider.container。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值