本博客属原创文章,欢迎转载!转载请务必注明出处:http://guoyunsky.iteye.com/blog/644396

      本博客已迁移到本人独立博客: http://www.yun5u.com/

       欢迎加入Heritrix群(QQ):109148319,10447185 , Lucene/Solr群(QQ) :  118972724

前面说过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,下面贴上代码:

  1. import java.io.BufferedReader;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.io.FileNotFoundException;
  5. import java.io.IOException;
  6. import java.io.InputStream;
  7. import java.io.InputStreamReader;
  8. import java.io.UnsupportedEncodingException;
  9. import java.sql.Connection;
  10. import java.sql.ResultSet;
  11. import java.sql.SQLException;
  12. import java.sql.Statement;
  13. import org.archive.crawler.frontier.RecoveryJournal;
  14. public class UrlToRecoverUtil {
  15. /**
  16. * 从文件中导入URl到recover.gz以便URL不再被抓取
  17. *
  18. * @param sourceFilePath        URL来源文件
  19. * @param sourceFileEncoding    URL来源文件的编码
  20. * @param recoverGzPath         要写到的recover.gz文件目录
  21. * @param recoverGzFileName     recover.gz文件名,可以为空
  22. * @return
  23. */
  24. public static boolean urlToRecoverUtilByFile(String sourceFilePath,String sourceFileEncoding,String recoverGzDir,String recoverGzFileName){
  25. boolean result=false;
  26. InputStream is=null;
  27. InputStreamReader isr=null;
  28. BufferedReader br=null;
  29. File sourceFile=null;
  30. String line=null;
  31. RecoveryJournal recover = null;
  32. try {
  33. sourceFile=new File(sourceFilePath);
  34. //recover.gz文件为空则采用默认名字
  35. if(recoverGzFileName==null||recoverGzFileName.equals("")){
  36. recoverGzFileName="recover.gz";
  37. }
  38. recover=new RecoveryJournal(recoverGzDir,recoverGzFileName);//构造recover.gz对象
  39. //读取文件内容
  40. is=new FileInputStream(sourceFile);
  41. isr=new InputStreamReader(is,sourceFileEncoding);
  42. br=new BufferedReader(isr);
  43. //一行一行写入recover.gz文件
  44. while((line=br.readLine().trim())!=null){
  45. if(!line.equals("")){
  46. recover.writeLine(RecoveryJournal.F_SUCCESS, line);
  47. }
  48. }
  49. result=true;
  50. } catch (FileNotFoundException e) {
  51. e.printStackTrace();
  52. } catch (UnsupportedEncodingException e) {
  53. e.printStackTrace();
  54. } catch (IOException e) {
  55. e.printStackTrace();
  56. }finally{
  57. try {
  58. if(recover!=null){
  59. recover.close();
  60. }
  61. if(br!=null){
  62. br.close();
  63. }
  64. if(isr!=null){
  65. isr.close();
  66. }
  67. if(is!=null){
  68. is.close();
  69. }
  70. } catch (IOException e) {
  71. e.printStackTrace();
  72. }
  73. }
  74. return result;
  75. }
  76. /**
  77. * 从ResultSet结果集中获取URL导入到recover.gz以便URl不再被抓取
  78. *
  79. * @param rs                ResultSet结果集
  80. * @param filedName         ResultSet结果集中要获取URL对应的字段名
  81. * @param recoverGzDir      要写到的recover.gz文件目录
  82. * @param recoverGzFileName recover.gz文件名,可以为空
  83. * @return
  84. */
  85. public static boolean urlToRecoverUtilByResultSet(ResultSet rs,String filedName,String recoverGzDir,String recoverGzFileName){
  86. boolean result=false;
  87. String line=null;
  88. RecoveryJournal recover = null;
  89. try {
  90. if(recoverGzFileName==null||recoverGzFileName.equals("")){
  91. recoverGzFileName="recover.gz";
  92. }
  93. recover=new RecoveryJournal(recoverGzDir,recoverGzFileName);
  94. if(rs!=null){
  95. while(rs.next()){
  96. line=rs.getString(filedName).trim();
  97. if(!line.equals("")){
  98. recover.writeLine(RecoveryJournal.F_SUCCESS, line);
  99. }
  100. }
  101. result=true;
  102. }
  103. } catch (SQLException e) {
  104. e.printStackTrace();
  105. } catch (IOException e) {
  106. e.printStackTrace();
  107. }finally{
  108. try {
  109. if(rs!=null){
  110. rs.close();
  111. }
  112. if(recover!=null){
  113. recover.close();
  114. }
  115. } catch (SQLException e) {
  116. e.printStackTrace();
  117. }
  118. }
  119. return result;
  120. }
  121. /**
  122. * @param args
  123. */
  124. public static void main(String[] args) {
  125. /*
  126. * 示例,从结果集中写入URL到recover.gz
  127. */
  128. Connection con=null;
  129. Statement stmt=null;
  130. ResultSet rs=null;
  131. String sql="SELECT CLASSIFY_INFO_URL FROM CLASSIFY_INFO";
  132. boolean result=false;
  133. try {
  134. con=DatabaseUtil.getConnection_Mysql_CrawlServer_Local();//获取Connection
  135. stmt=con.createStatement();
  136. rs=stmt.executeQuery(sql);
  137. result=urlToRecoverUtilByResultSet(rs,"CLASSIFY_INFO_URL","D:/HeritrixRecover/",null);
  138. System.out.println("从结果集中导入URL到recover.gz文件:"+(result?"成功!":"失败!"));
  139. } catch (SQLException e) {
  140. // TODO Auto-generated catch block
  141. e.printStackTrace();
  142. }finally{
  143. DatabaseUtil.closeConnection(con, stmt, rs);//关闭Connection、Statement、ResultSet
  144. }
  145. }
  146. }

这个工具类其实主要也只是生成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的更多相关文章

  1. Heritrix源码分析(十四) 如何让Heritrix不间断的抓取(转)

    欢迎加入Heritrix群(QQ):109148319,10447185 , Lucene/Solr群(QQ) :  118972724 本博客已迁移到本人独立博客: http://www.yun5u ...

  2. Heritrix源码分析(十四)

    近段时间在搞定Lucene的一些问题,所以Heritrix源码分析暂时告一段落.今天下午在群里有同学提到了Heritrix异常终止的问题以及让Heritrix不停的抓取(就是抓完一遍后载入种子继续抓取 ...

  3. 手机自动化测试:appium源码分析之bootstrap十二

    手机自动化测试:appium源码分析之bootstrap十二   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣 ...

  4. HDFS源码分析之UnderReplicatedBlocks(二)

    UnderReplicatedBlocks还提供了一个数据块迭代器BlockIterator,用于遍历其中的数据块.它是UnderReplicatedBlocks的内部类,有三个成员变量,如下: // ...

  5. 【集合框架】JDK1.8源码分析之LinkedHashMap(二)

    一.前言 前面我们已经分析了HashMap的源码,已经知道了HashMap可以用在哪种场合,如果这样一种情形,我们需要按照元素插入的顺序来访问元素,此时,LinkedHashMap就派上用场了,它保存 ...

  6. 【JUC】JDK1.8源码分析之AbstractQueuedSynchronizer(二)

    一.前言 在锁框架中,AbstractQueuedSynchronizer抽象类可以毫不夸张的说,占据着核心地位,它提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.所以很有必 ...

  7. 【JUC】JDK1.8源码分析之ConcurrentSkipListMap(二)

    一.前言 最近在做项目的同时也在修复之前项目的一些Bug,所以忙得没有时间看源代码,今天都完成得差不多了,所以又开始源码分析之路,也着笔记录下ConcurrentSkipListMap的源码的分析过程 ...

  8. 【Zookeeper】源码分析之网络通信(二)

    一.前言 前面介绍了ServerCnxn,下面开始学习NIOServerCnxn. 二.NIOServerCnxn源码分析 2.1 类的继承关系 public class NIOServerCnxn ...

  9. 【Zookeeper】源码分析之服务器(二)

    一.前言 前面阐述了服务器的总体框架,下面来分析服务器的所有父类ZooKeeperServer. 二.ZooKeeperServer源码分析 2.1 类的继承关系 public class ZooKe ...

随机推荐

  1. .htaccess的基本作用及相关语法介绍

    .htaccess是一个纯文本文件,它里面存放着Apache服务器配置相关的指令. .htaccess主要的作用有:URL重写.自定义错误页面.MIME类型配置以及访问权限控制等.主要体现在伪静态的应 ...

  2. ExtJs之Ext.core.DomHelper.append

    <!DOCTYPE html> <html> <head> <title>ExtJs</title> <meta http-equiv ...

  3. (转)OpenCV 2.4.8 +VS2010的开发环境配置

    转自:  http://blog.csdn.net/poem_qianmo/article/details/19809337 自己可能需要再进行修改 本系列文章由zhmxy555(毛星云)编写,转载请 ...

  4. Linux网络编程6——使用TCP实现文件服务器

    需求 当客户端连接上服务器后,服务器会将相应文件传输给客户端,实现文件下载. 思路 服务器端,主进程负责listen.循环内,主进程每从任务请求队列中accept出一个请求,就fork出孙子完成文件传 ...

  5. Servlet3.0-使用注解定义Servlet

    我使用的开发环境:MyEclipse10+Tomcat7+JDK6. 开发Servlet3的程序需要一定的环境支持.Servlet3是Java EE6规范的一部分,MyEclipse10和Tomcat ...

  6. 浏览器的CSS各种hack,大汇总

    对着IE久了也有感觉了,在win10出新浏览器以及中国的IE6+用户没有普及新的浏览器前IE还是个坑,所以hack这东西还是要掌握一点的.不废话直接贴图 记得之前在项目里面针对IE6的hack是这样写 ...

  7. lintcode:字符串置换

    题目 给定两个字符串,请设计一个方法来判定其中一个字符串是否为另一个字符串的置换. 置换的意思是,通过改变顺序可以使得两个字符串相等. 样例 "abc" 为 "cba&q ...

  8. myeclipse 8.6 安装svn插件

    第一种:在线安装 1.打开HELP->MyEclipse Configuration Center,切换到SoftWare标签页. 2.点击Add Site 打开对话框,在对话框Name输入Sv ...

  9. React属性的3种设置方式

    一. 不推荐用setProps,因为以React的设计思想相悖,推荐以父组件向子组件传递属性的方式 二.3种用法的代码 1.键值对 <!DOCTYPE html> <html lan ...

  10. Dreamweaver修改页面编码

    想修改当前页面编码,可以选择菜单 :修改->页面属性->标题/编码 想设置新建页面默认编码,可以选择菜单: 编辑->首选参数->新建文档 的默认编码里面修改