Heritrix源码分析(九) Heritrix的二次抓取以及如何让Heritrix抓取你不想抓取的URL
2013-04-30 16:30
260 查看
前面说过Heritrix可以在某个抓取基础上(这里假设为A)继续抓取,因为Heritrix对每一个URL都会有相应的日志处理,同时还有checkpoint(备份中心)。所以只要通过A上的日志就可以完全按照该基础A继续抓取,不会重复抓取任何A抓过的任何东西,也会继续抓取A没有抓过的URL。做到这个有两种方法,一种是针对Web启动的,还有一种是针对我上次写的不通过Web启动的方式(启动方式见博客:Heritrix源码分析(五)
如何让Heritrix在Ecplise等IDE下编程启动).
1)下面介绍这两种启动方式,第一种,通过Web启动:
进入页面,选择:Jobs->Base on a recovery->然后再选择你要二次抓取的Job中的recover-log->然后再点击按钮Submit Job。之后回到Console页面,点击Start。之后就开始再你想要的基础上抓取了。你可以进入这个新建的抓取JOB下的logs目录,发现里面有个recover.gz大小跟你想要二次抓取JOB中的recover.gz大小一般大。以及你去查看该job下的order.xml中的<string name="recover-path"></string>中间的值发现就是你要二次抓取job下recover.gz的绝对目录
2)不通过Web方式启动:
这个相对简单,只要修改order.xml中<string name="recover-path">D:/recover.gz</string>,中间的值就是你想二次抓取的JOB中logs目录下recover.gz的绝对路径。
同时最好更新一下值为:
<boolean name="checkpoint-copy-bdbje-logs">true</boolean>
<boolean name="recover-retain-failures">false</boolean>
<boolean name="recover-scope-includes">false</boolean>
<boolean name="recover-scope-enqueues">false</boolean>
至于为什么要这样设置,请参考我关于order.xml介绍的博客:Heritrix源码分析(二) 配置文件order.xml介绍
同时可能你已经知道某些URL不需要抓取,比如从数据库导出来的,而这些URL你的Heritrix并没有处理过。所以这些外部的URL就无法通过以上两种办法导入Heritrix了。这里我写了个工具类,有两种方式,一种是你将URL都放在文件中,然后通过这个工具类从这个文件中读取这些URL(必须一行一个URL),导入到Heritrix中。还有一种方法是针对数据库的,你只要提供相应的ResultSet以及该URL对应数据库的字段名,也可以导入Heritrix,下面贴上代码:
Java代码
![](http://image14.360doc.com/DownloadImg/2010/09/1413/5267557_1.gif)
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.archive.crawler.frontier.RecoveryJournal;
public class UrlToRecoverUtil {
/**
* 从文件中导入URl到recover.gz以便URL不再被抓取
*
* @param sourceFilePath URL来源文件
* @param sourceFileEncoding URL来源文件的编码
* @param recoverGzPath 要写到的recover.gz文件目录
* @param recoverGzFileName recover.gz文件名,可以为空
* @return
*/
public static boolean urlToRecoverUtilByFile(String sourceFilePath,String sourceFileEncoding,String recoverGzDir,String recoverGzFileName){
boolean result=false;
InputStream is=null;
InputStreamReader isr=null;
BufferedReader br=null;
File sourceFile=null;
String line=null;
RecoveryJournal recover = null;
try {
sourceFile=new File(sourceFilePath);
//recover.gz文件为空则采用默认名字
if(recoverGzFileName==null||recoverGzFileName.equals("")){
recoverGzFileName="recover.gz";
}
recover=new RecoveryJournal(recoverGzDir,recoverGzFileName);//构造recover.gz对象
//读取文件内容
is=new FileInputStream(sourceFile);
isr=new InputStreamReader(is,sourceFileEncoding);
br=new BufferedReader(isr);
//一行一行写入recover.gz文件
while((line=br.readLine().trim())!=null){
if(!line.equals("")){
recover.writeLine(RecoveryJournal.F_SUCCESS, line);
}
}
result=true;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(recover!=null){
recover.close();
}
if(br!=null){
br.close();
}
if(isr!=null){
isr.close();
}
if(is!=null){
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
/**
* 从ResultSet结果集中获取URL导入到recover.gz以便URl不再被抓取
*
* @param rs ResultSet结果集
* @param filedName ResultSet结果集中要获取URL对应的字段名
* @param recoverGzDir 要写到的recover.gz文件目录
* @param recoverGzFileName recover.gz文件名,可以为空
* @return
*/
public static boolean urlToRecoverUtilByResultSet(ResultSet rs,String filedName,String recoverGzDir,String recoverGzFileName){
boolean result=false;
String line=null;
RecoveryJournal recover = null;
try {
if(recoverGzFileName==null||recoverGzFileName.equals("")){
recoverGzFileName="recover.gz";
}
recover=new RecoveryJournal(recoverGzDir,recoverGzFileName);
if(rs!=null){
while(rs.next()){
line=rs.getString(filedName).trim();
if(!line.equals("")){
recover.writeLine(RecoveryJournal.F_SUCCESS, line);
}
}
result=true;
}
} catch (SQLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(rs!=null){
rs.close();
}
if(recover!=null){
recover.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
return result;
}
/**
* @param args
*/
public static void main(String[] args) {
/*
* 示例,从结果集中写入URL到recover.gz
*/
Connection con=null;
Statement stmt=null;
ResultSet rs=null;
String sql="SELECT CLASSIFY_INFO_URL FROM CLASSIFY_INFO";
boolean result=false;
try {
con=DatabaseUtil.getConnection_Mysql_CrawlServer_Local();//获取Connection
stmt=con.createStatement();
rs=stmt.executeQuery(sql);
result=urlToRecoverUtilByResultSet(rs,"CLASSIFY_INFO_URL","D:/HeritrixRecover/",null);
System.out.println("从结果集中导入URL到recover.gz文件:"+(result?"成功!":"失败!"));
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
DatabaseUtil.closeConnection(con, stmt, rs);//关闭Connection、Statement、ResultSet
}
}
}
这个工具类其实主要也只是生成recover.gz文件。如果你采用Web方式启动,你只要找到一个你抓取过的JOB,然后用这个生成的recover.gz目录覆盖你找到job下logs目录中的recover.gz即可。而如果你采用非Web启动就更简单了,只要将order.xml中<string name="recover-path">D:/recover.gz</string>中的值改成你生成recover.gz绝对路径即可!
如何让Heritrix在Ecplise等IDE下编程启动).
1)下面介绍这两种启动方式,第一种,通过Web启动:
进入页面,选择:Jobs->Base on a recovery->然后再选择你要二次抓取的Job中的recover-log->然后再点击按钮Submit Job。之后回到Console页面,点击Start。之后就开始再你想要的基础上抓取了。你可以进入这个新建的抓取JOB下的logs目录,发现里面有个recover.gz大小跟你想要二次抓取JOB中的recover.gz大小一般大。以及你去查看该job下的order.xml中的<string name="recover-path"></string>中间的值发现就是你要二次抓取job下recover.gz的绝对目录
2)不通过Web方式启动:
这个相对简单,只要修改order.xml中<string name="recover-path">D:/recover.gz</string>,中间的值就是你想二次抓取的JOB中logs目录下recover.gz的绝对路径。
同时最好更新一下值为:
<boolean name="checkpoint-copy-bdbje-logs">true</boolean>
<boolean name="recover-retain-failures">false</boolean>
<boolean name="recover-scope-includes">false</boolean>
<boolean name="recover-scope-enqueues">false</boolean>
至于为什么要这样设置,请参考我关于order.xml介绍的博客:Heritrix源码分析(二) 配置文件order.xml介绍
同时可能你已经知道某些URL不需要抓取,比如从数据库导出来的,而这些URL你的Heritrix并没有处理过。所以这些外部的URL就无法通过以上两种办法导入Heritrix了。这里我写了个工具类,有两种方式,一种是你将URL都放在文件中,然后通过这个工具类从这个文件中读取这些URL(必须一行一个URL),导入到Heritrix中。还有一种方法是针对数据库的,你只要提供相应的ResultSet以及该URL对应数据库的字段名,也可以导入Heritrix,下面贴上代码:
Java代码
![](http://image14.360doc.com/DownloadImg/2010/09/1413/5267557_1.gif)
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.archive.crawler.frontier.RecoveryJournal;
public class UrlToRecoverUtil {
/**
* 从文件中导入URl到recover.gz以便URL不再被抓取
*
* @param sourceFilePath URL来源文件
* @param sourceFileEncoding URL来源文件的编码
* @param recoverGzPath 要写到的recover.gz文件目录
* @param recoverGzFileName recover.gz文件名,可以为空
* @return
*/
public static boolean urlToRecoverUtilByFile(String sourceFilePath,String sourceFileEncoding,String recoverGzDir,String recoverGzFileName){
boolean result=false;
InputStream is=null;
InputStreamReader isr=null;
BufferedReader br=null;
File sourceFile=null;
String line=null;
RecoveryJournal recover = null;
try {
sourceFile=new File(sourceFilePath);
//recover.gz文件为空则采用默认名字
if(recoverGzFileName==null||recoverGzFileName.equals("")){
recoverGzFileName="recover.gz";
}
recover=new RecoveryJournal(recoverGzDir,recoverGzFileName);//构造recover.gz对象
//读取文件内容
is=new FileInputStream(sourceFile);
isr=new InputStreamReader(is,sourceFileEncoding);
br=new BufferedReader(isr);
//一行一行写入recover.gz文件
while((line=br.readLine().trim())!=null){
if(!line.equals("")){
recover.writeLine(RecoveryJournal.F_SUCCESS, line);
}
}
result=true;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(recover!=null){
recover.close();
}
if(br!=null){
br.close();
}
if(isr!=null){
isr.close();
}
if(is!=null){
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
/**
* 从ResultSet结果集中获取URL导入到recover.gz以便URl不再被抓取
*
* @param rs ResultSet结果集
* @param filedName ResultSet结果集中要获取URL对应的字段名
* @param recoverGzDir 要写到的recover.gz文件目录
* @param recoverGzFileName recover.gz文件名,可以为空
* @return
*/
public static boolean urlToRecoverUtilByResultSet(ResultSet rs,String filedName,String recoverGzDir,String recoverGzFileName){
boolean result=false;
String line=null;
RecoveryJournal recover = null;
try {
if(recoverGzFileName==null||recoverGzFileName.equals("")){
recoverGzFileName="recover.gz";
}
recover=new RecoveryJournal(recoverGzDir,recoverGzFileName);
if(rs!=null){
while(rs.next()){
line=rs.getString(filedName).trim();
if(!line.equals("")){
recover.writeLine(RecoveryJournal.F_SUCCESS, line);
}
}
result=true;
}
} catch (SQLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(rs!=null){
rs.close();
}
if(recover!=null){
recover.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
return result;
}
/**
* @param args
*/
public static void main(String[] args) {
/*
* 示例,从结果集中写入URL到recover.gz
*/
Connection con=null;
Statement stmt=null;
ResultSet rs=null;
String sql="SELECT CLASSIFY_INFO_URL FROM CLASSIFY_INFO";
boolean result=false;
try {
con=DatabaseUtil.getConnection_Mysql_CrawlServer_Local();//获取Connection
stmt=con.createStatement();
rs=stmt.executeQuery(sql);
result=urlToRecoverUtilByResultSet(rs,"CLASSIFY_INFO_URL","D:/HeritrixRecover/",null);
System.out.println("从结果集中导入URL到recover.gz文件:"+(result?"成功!":"失败!"));
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
DatabaseUtil.closeConnection(con, stmt, rs);//关闭Connection、Statement、ResultSet
}
}
}
这个工具类其实主要也只是生成recover.gz文件。如果你采用Web方式启动,你只要找到一个你抓取过的JOB,然后用这个生成的recover.gz目录覆盖你找到job下logs目录中的recover.gz即可。而如果你采用非Web启动就更简单了,只要将order.xml中<string name="recover-path">D:/recover.gz</string>中的值改成你生成recover.gz绝对路径即可!
相关文章推荐
- Heritrix源码分析(九) Heritrix的二次抓取以及如何让Heritrix抓取你不想抓取的URL
- Heritrix源码分析(九) Heritrix的二次抓取以及如何让Heritrix抓取你不想抓取的URL
- Heritrix1.14源码分析(9) Heritrix的二次抓取以及如何让Heritrix抓取你不想抓取的URL
- Heritrix1.14源码分析(9) Heritrix的二次抓取以及如何让Heritrix抓取你不想抓取的URL
- Heritrix源码分析(十一) Heritrix中的URL--CandidateURI和CrawlURI以及如何增加自己的属性
- Heritrix源码分析(十一) Heritrix中的URL--CandidateURI和CrawlURI以及如何增加自己的属性(转)
- Heritrix1.14源码分析(11) Heritrix中的URL--CandidateURI和CrawlURI以及如何增加自己的属性
- Heritrix1.14源码分析(11) Heritrix中的URL--CandidateURI和CrawlURI以及如何增加自己的属性
- Heritrix源码分析(十四) 如何让Heritrix不间断的抓取(转)
- Heritrix1.14源码分析(13) 如何让Heritrix不间断的抓取
- Heritrix1.14源码分析(13) 如何让Heritrix不间断的抓取
- android smack源码分析——接收消息以及如何解析消息
- Sqlite创建database的两种方法,以及源码分析,以及抽象类如何在SqliteHelper中应用
- Heritrix源码分析(三) 修改配置文件order.xml加快你的抓取速度
- memcached源码分析-----安装、调试以及如何阅读memcached源码
- android smack源码分析——接收消息以及如何解析消息
- android smack源码分析——接收消息以及如何解析消息【3】
- Heritrix源码分析(五) 如何让Heritrix在Ecplise等IDE下编程启动(转)
- Heritrix1.14源码分析(3) 修改配置文件order.xml加快你的抓取速度
- Heritrix1.14源码分析(3) 修改配置文件order.xml加快你的抓取速度