走进 Apache Nutch (v1.14)

Apache Nutch


Apache Nutch 起源于 Apache Lucene 项目,是高可扩展性和高可伸缩性的开源 web 爬虫软件项目。项目主页:

    http://nutch.apache.org/
    
出于底层数据存储多样性的设计,目前该项目在两个代码分支上持续开发,分别是:

    ● Nutch 1.x :成熟的产品级 web 爬虫,这个分支通过精细的优化配制,充分利用了具有非常强大的批处理能力的Apache Hadoop数据
                  结构。目前该分支最新版本是 2017 年12月23日发布的 Nutch 1.14,基于 Hadoop 2.7.4 版本开发。
                  
                  通过如下网址访问该版本的发布报告:
                  
                  https://issues.apache.org/jira/secure/ReleaseNote.jspa?projectId=10680&version=12340218
                        

    ● Nutch 2.x :从 1.x 分离出来的新兴版本,最重要的不同在于:将底层具体的数据存储抽象为存储层,利用 Apache Gora 作为数据
                  中间层来处理对象的持久化映射。这样用户可以实现非常灵活数据模型来存储任何数据到各种类型的 NoSQL 存储方案中,
                  例如,抓取时间(etch time), 状态(status), 内容(content), 解析的文本(parsed text), 出链(outlinks),入链 (
                  inlinks) 等等。
                  
                  目前该分支的最新版本是 2016 年1月21日发布的 Nutch 2.3.1。通过如下网址访问该版本的发布报告:
                  
                  https://issues.apache.org/jira/secure/ReleaseNote.jspa?projectId=10680&version=12329371

                  该版本建议的 Gora 后端数据存储层为:
                  
                    □ Apache Avro 1.7.6
                    □ Apache Hadoop 1.2.1 and 2.5.2
                    □ Apache HBase 0.98.8-hadoop2 (although also tested with 1.X)
                    □ Apache Cassandra 2.0.2
                    □ Apache Solr 4.10.3
                    □ MongoDB 2.6.X
                    □ Apache Accumlo 1.5.1
                    □ Apache Spark 1.4.1

                  根据 2018-1-17 和 2018-4-18 的 nutch 核心团队会议备忘录(Nutch Board meeting minutes),目前 nutch 2.4 版正在开发
                  当中,计划几周之后发布:
                  
                    https://whimsy.apache.org/board/minutes/Nutch.html
                  
                    ...
                    The release of 2.4 is on the agenda.

                    ...
                    We plan to release 2.4 during the next weeks.
                  
                  
通过其可插入式和模块化的设计,Nutch 提供了可扩展性接口,例如 Parse,Index 以及 ScoringFilter 用于用户自定义实现。例如,
Apache Tika 就是 Parse 的实现。另外,有为 Apache Solr, SolrCloud, Elastic Search 等实现的可插入式索引 (indexing) 模块。


Nutch 可以在单独的机器上运行,但要获得其强大的高可扩展性和高可伸缩性分布式处理能力还是要将其运行在 Hadoop 集群上。

 

1. 系统要求 (Requirements):
-------------------------------------------------------------------------------------------------------------------------
    ● Linux/Unix 环境,或 windows Cygwin 环境
    ● JDK 1.8/Java 8
    ● Apache Ant (只有从源代码构建时需要)


2. Nutch 安装 (Install Nutch):
-------------------------------------------------------------------------------------------------------------------------
下载页面:

    http://nutch.apache.org/downloads.html


Nutch 本地安装有两种选择:


2.1 二进制发布包安装(from a binary distribution) 步骤
-------------------------------------------------------------------------------------------------------------------------
① 下载 nutch 二进制发布包:
    
    尽量从本地区镜像站点下载,速度较快,下面是清华镜像站点下载地址:
    
    https://mirrors.tuna.tsinghua.edu.cn/apache/nutch/1.14/apache-nutch-1.14-bin.tar.gz
    
② 解压下载的二进制包:

        [devalone@nutch ~]$ tar -zxvf apache-nutch-1.14-bin.tar.gz
        
        [devalone@nutch ~]$ ll
        总用量 243272
        drwxrwxr-x 7 devalone devalone       123 7月  19 15:50 apache-nutch-1.14
        -rw-rw-r-- 1 devalone devalone 249107211 7月  19 15:48 apache-nutch-1.14-bin.tar.gz

    
③ 安装 apache-nutch-1.14

    将解压的 得到 apache-nutch-1.14 文件夹移动到合适的安装位置,例如安装到 /opt/nutch/ 目录下:
    
        [devalone@nutch ~]$ sudo mv apache-nutch-1.14 /opt/nutch/
    
    创建合适的符号链接,以利于不同版本 nutch 管理,例如:
    
    [devalone@nutch nutch]$ pwd
    /opt/nutch
    [devalone@nutch nutch]$ ls -l
    总用量 0
    drwxrwxr-x 7 devalone devalone 123 6月  29 16:52 apache-nutch-1.14
    lrwxrwxrwx 1 root     root       8 6月  29 17:01 nutch -> nutch1.x
    lrwxrwxrwx 1 root     root      17 6月  29 17:00 nutch1.x -> apache-nutch-1.14
    
    编辑 /etc/profile 文件,在其中建立 NUTCH_INSTALL 环境变量,修改 PATH 环境变量,将 nutch/bin 包含到 PATH 中,如下所示:
    
        JAVA_HOME=/usr/java/default
        PATH=$JAVA_HOME/bin:$PATH

        NUTCH_INSTALL=/opt/nutch/nutch
        PATH=$NUTCH_INSTALL/bin:$PATH

        export PATH JAVA_HOME NUTCH_INSTALL
    
    保存文件,执行 source /etc/profile 使其立即生效。
    
    
    NOTE:
    ---------------------------------------------------------------------------------------------------------------------
    NUTCH_HOME 环境变量在 nutch 脚本内部使用,因此在 shell 环境中配置时尽量不要使用这个变量,以免造成不必要的麻烦。
    
        
    NOTE:
    ---------------------------------------------------------------------------------------------------------------------
    Nutch 发布的二进制发布包只适用于本机模式,不适用于分布式环境运行。因此,要在 hadoop 分布式或伪分布式环境中运行 Nutch,
    必须使用源代码编译方式。
    
    

2.2 Nutch 源码安装(from a source distribution) 步骤
-------------------------------------------------------------------------------------------------------------------------


2.2.1 构建 Nutch 编译环境
-------------------------------------------------------------------------------------------------------------------------
源码安装 Nutch 需要 ant 配合 ivy 依赖类库构建编译环境,过程如下:

    [devalone@online apache]$ wget http://mirrors.tuna.tsinghua.edu.cn/apache//ant/binaries/apache-ant-1.10.5-bin.tar.gz
    [devalone@online apache]$ wget http://mirrors.hust.edu.cn/apache//ant/ivy/2.5.0-rc1/apache-ivy-2.5.0-rc1-bin.tar.gz

    [devalone@online apache]$ ll
    总用量 8352
    -rw-rw-r--. 1 devalone devalone 5829814 7月  13 18:10 apache-ant-1.10.5-bin.tar.gz
    -rw-rw-r--. 1 devalone devalone 2716983 4月  12 23:46 apache-ivy-2.5.0-rc1-bin.tar.gz

    [devalone@nutch apache]$ tar -zxvf apache-ant-1.10.5-bin.tar.gz
    [devalone@nutch apache]$ tar -zxvf apache-ivy-2.5.0-rc1-bin.tar.gz

    [devalone@nutch apache]$ sudo mv apache-ant-1.10.5-bin.tar.gz /usr/local/lib/apache/ant/
    [devalone@nutch apache]$ cd /usr/local/lib/apache/ant/
    [devalone@nutch ant]$ sudo ln -s apache-ant-1.10.5 ant

    [devalone@nutch ant]$ pwd
    /usr/local/lib/apache/ant/ant

将 ivy 的 jar 包复制到 ant 的 lib/ 目录下:

    [devalone@nutch apache-ivy-2.5.0-rc1]$ cp ivy-2.5.0-rc1.jar /usr/local/lib/apache/ant/ant/lib/
    
    NOTE:
    ---------------------------------------------------------------------------------------------------------------------
    实际上 nutch 源码包 ivy/ 目录下自带了 ivy-2.4.0.jar 文件,也可以直接使用这个 jar 包文件,而不必自己单独下载 ivy 的 jar
    文件。
    

编辑 /etc/profile 文件,设置 ANT_HOME 环境变量,并将 ant/bin 添加到 PATH 中:

    JAVA_HOME=/usr/java/default
    PATH=$JAVA_HOME/bin:$PATH

    ANT_HOME=/usr/local/lib/apache/ant/ant
    PATH=$ANT_HOME/bin:$PATH

    NUTCH_INSTALL=/opt/nutch/nutch
    PATH=$NUTCH_INSTALL/bin:$PATH

    export PATH JAVA_HOME ANT_HOME NUTCH_INSTALL
        
保存退出,执行:

    [devalone@nutch ant]$ source /etc/profile

    使其立即生效。

    [devalone@nutch ant]$ ant -version
    Apache Ant(TM) version 1.10.5 compiled on July 10 2018
    
编译环境安装完成。


2.2.2 执行 Nutch 源码安装
-------------------------------------------------------------------------------------------------------------------------
① 下载 Nutch 源码包,同样使用清华镜像站点下载:

    https://mirrors.tuna.tsinghua.edu.cn/apache/nutch/1.14/apache-nutch-1.14-src.tar.gz

② 解压源码包:

    [devalone@nutch ~]$ tar -zxvf apache-nutch-1.14-src.tar.gz

    [devalone@nutch ~]$ ll
    总用量 5268
    drwxrwxr-x 3 devalone devalone     109 7月  20 10:12 apache
    drwxrwxr-x 7 devalone devalone     162 7月  20 10:36 apache-nutch-1.14
    -rw-rw-r-- 1 devalone devalone 5390394 7月  20 10:36 apache-nutch-1.14-src.tar.gz


③ 进入解压后的源码目录: apache-nutch-1.14

    [devalone@nutch ~]$ cd apache-nutch-1.14

    [devalone@nutch apache-nutch-1.14]$ ll
    总用量 504
    -rw-rw-r-- 1 devalone devalone  54529 12月 19 2017 build.xml
    -rw-rw-r-- 1 devalone devalone 106848 12月 19 2017 CHANGES.txt
    drwxr-xr-x 2 devalone devalone   4096 7月  20 10:36 conf
    -rw-rw-r-- 1 devalone devalone   6297 12月 19 2017 default.properties
    drwxr-xr-x 3 devalone devalone     17 12月 19 2017 docs
    drwxr-xr-x 2 devalone devalone    148 7月  20 10:36 ivy
    drwxr-xr-x 3 devalone devalone     20 12月 19 2017 lib
    -rw-rw-r-- 1 devalone devalone 329066 12月 19 2017 LICENSE.txt
    -rw-rw-r-- 1 devalone devalone    427 12月 19 2017 NOTICE.txt
    drwxr-xr-x 7 devalone devalone     76 12月 19 2017 src

    
④ 在当前目录下执行源码编译:

    ● sonar-ant-task-2.2.jar
    ---------------------------------------------------------------------------------------------------------------------
    编译 nutch 依赖 sonar-ant-task-2.2.jar 任务包,但 ivy 无法加载该包的资源定义 org/sonar/ant/antlib.xml,需要手动下载,
    否则出现如下错误:
        [taskdef] Could not load definitions from resource org/sonar/ant/antlib.xml. It could not be found.
        ivy-download:
        [taskdef] Could not load definitions from resource org/sonar/ant/antlib.xml. It could not be found.

    下载地址:
        https://download.csdn.net/download/devalone/10554266
    
    将下载解压的 sonar-ant-task-2.2.jar 包文件复制到 ant/lib/ 目录下:
        [devalone@nutch ant]$ sudo cp ~/sonar-ant-task-2.2.jar ant/lib/
        
        
    ● 编辑 ivy/ivysettings.xml 文件,替换较快的 ivy 仓库:
    ---------------------------------------------------------------------------------------------------------------------
    [devalone@nutch apache-nutch-1.14]$ vi ivy/ivysettings.xml
    
    Nutch 的 ivysettings.xml 配置了 3 个 maven 模块仓库:
       
               value="http://oss.sonatype.org/content/repositories/releases/"
        override="false"/>
              value="http://repo1.maven.org/maven2/"
        override="false"/>
              value="https://repository.apache.org/content/repositories/snapshots/"
        override="false"/>
    
    
    将这 3 个仓库替换为较快的仓库,示例:
    
        http://maven.aliyun.com/nexus/content/groups/public/
        http://maven.aliyun.com/nexus/content/repositories/central/
        http://maven.aliyun.com/nexus/content/repositories/apache-snapshots/
        
    
    本例使用本地网络环境内配置好的 maven 仓库:
    
               value="http://repo.sansovo.org:8081/nexus/content/groups/public/"
        override="false"/>
              value="http://repo.sansovo.org:8081/nexus/content/groups/public/"
        override="false"/>
              value="http://repo.sansovo.org:8081/nexus/content/groups/public-snapshot/"
        override="false"/>


    ● 执行编译:
    ---------------------------------------------------------------------------------------------------------------------
    [devalone@nutch apache-nutch-1.14]$ ant
    Buildfile: /home/devalone/apache-nutch-1.14/build.xml
    Trying to override old definition of task javac

    ivy-probe-antlib:

    ivy-download:

    ivy-download-unchecked:

    ivy-init-antlib:

    ivy-init:

    init:

    clean-default-lib:

    resolve-default:
    [ivy:resolve] :: Apache Ivy 2.5.0-rc1 - 20180412005306 :: http://ant.apache.org/ivy/ ::
    [ivy:resolve] :: loading settings :: file = /home/devalone/apache-nutch-1.14/ivy/ivysettings.xml
    [ivy:resolve] downloading http://repo.sansovo.org:8081/nexus/content/groups/public/org/apache/commons
    /commons-compress/1.14/commons-compress-1.14.jar ...
    [ivy:resolve] ........................................................................................
    ......................................... (517kB)
    [ivy:resolve] .. (0kB)
    [ivy:resolve]   [SUCCESSFUL ] org.apache.commons#commons-compress;1.14!commons-compress.jar (6470ms)
    [ivy:resolve] downloading http://repo.sansovo.org:8081/nexus/content/groups/public/org/apache/hadoop/
    hadoop-common/2.7.4/hadoop-common-2.7.4.jar ...
    [ivy:resolve] ........................................................................................
    ..............................................
    
    ....
    

    BUILD SUCCESSFUL
    Total time: 28 minutes 5 seconds

    NOTE:
    ---------------------------------------------------------------------------------------------------------------------
    第一次构建过程中最好不要中断,以免 ivy 依赖库文件下载损坏,使编译发生一些奇怪的错误。如果确实出现错误,可以清除掉
    ~/.ivy2/cache/ 目录重新构建。

    之后如果再次构建,~/.ivy2 库已完整下载,构建会很快完成,如:
    
    ...
    BUILD SUCCESSFUL
    Total time: 35 seconds


⑤ 编译完成后,在源码目录下生成 runtime 目录,该目录下即是构建出的二进制可执行文件包:

    [devalone@nutch apache-nutch-1.14]$ ll runtime/
    总用量 0
    drwxrwxr-x 3 devalone devalone 46 7月  21 11:36 deploy
    drwxrwxr-x 7 devalone devalone 67 7月  21 11:37 local

其中 deploy 目录为分布式可执行文件包,local 目录为本地模式可执行文件包。将 local 目录按照 "二进制发布包安装" 中提示的方法
安装到合适的目录下即可。

    NOTE:
    ---------------------------------------------------------------------------------------------------------------------
    执行 ant clean 指令会清除 runtime 目录,注意备份配置文件。


2.3 验证 Nutch 安装
-------------------------------------------------------------------------------------------------------------------------
无论使用哪种方式安装,运行如下指令:

    [devalone@nutch ~]$ nutch
    nutch 1.14
    Usage: nutch COMMAND
    where COMMAND is one of:
      readdb            read / dump crawl db
      mergedb           merge crawldb-s, with optional filtering
      readlinkdb        read / dump link db
      inject            inject new urls into the database
      generate          generate new segments to fetch from crawl db
      freegen           generate new segments to fetch from text files
      fetch             fetch a segment's pages
      parse             parse a segment's pages
      readseg           read / dump segment data
      mergesegs         merge several segments, with optional filtering and slicing
    ...

输出 nutch 程序的版本号和使用方法,以及命令简要说明,说明 Nutch 本地模式运行已成功安装。


    NOTE:
    ---------------------------------------------------------------------------------------------------------------------
    最好将本机主机名指向准确的 IP 地址,避免不必要的错误,下面是这台测试机器的设置(有 DNS 配置更好):
    
        [devalone@nutch ~]$ cat /etc/hosts
        127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4 nutch.sansovo.org nutch
        ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6 nutch.sansovo.org nutch
        192.168.1.113   nutch.sansovo.org nutch
    


3. 爬取 web 站点
-------------------------------------------------------------------------------------------------------------------------
在爬取 web 站点之前,nutch 要求必须要做两处配置:

    ① 配置爬取属性,至少要配置爬虫名称。
    ② 配置要爬取的 URL 种子列表。


    
3.1 配置爬取属性
-------------------------------------------------------------------------------------------------------------------------
默认的爬取属性由 $NUTCH_INSTALL/conf/nutch-default.xml 文件设置,不要在这个文件内修改配置,即多数情况下不要修改此文件,最好
将其设为只读属性。nutch-default.xml 文件中包含了所有属性及其说明,应花些时间仔细研读每一个属性的说明,有利于理解和深度配置
nutch 程序。

$NUTCH_INSTALL/conf/nutch-site.xml文件用于配置自定义的爬取属性,这个文件中配置的属性会覆盖 $NUTCH_INSTALL/conf/nutch-default.xml
文件中配置的默认属性值。因此,应将所有的自定义配置属性设置在 $NUTCH_INSTALL/conf/nutch-site.xml 文件中。

● nutch 要求在运行前至少要配置 http.agent.name 属性。因此打开 conf/nutch-site.xml 文件,配置类似如下的内容:

    [devalone@nutch nutch]$ vi conf/nutch-site.xml
    
     http.agent.name
     My Nutch Spider
    

    该属性值随便设置一个合理的字符串,只要不是空串或空白串就好。

    NOTE:
    ---------------------------------------------------------------------------------------------------------------------
    http.agent.name 属性的配置其实是有些讲究的。有些站点会配置 robots 协议或者其他机制禁止网络爬虫的爬取。针对 robots 协
    议,可以将 http.agent.name 设置为正常浏览器 User-Agent 请求头属性值。获取方法很多,这里不赘述。示例:

    
      http.agent.name
      Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0
      HTTP 'User-Agent' request header. MUST NOT be empty -
      please set this to a single word uniquely related to your organization.

      NOTE: You should also check other related properties:

        http.robots.agents
        http.agent.description
        http.agent.url
        http.agent.email
        http.agent.version

      and set their values appropriately.

     
    
    
    或者 Linux 上的:
    
        Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0

    可通过百度资源平台 https://ziyuan.baidu.com/robots 对网站的 robots 配置进行检测分析,了解某个网站的 robots 配置情况。
    
● 另外要确认 plugin.includes 属性中包含所索引器插件 indexer-solr,用于之后建立 solr 索引。该属性在默认配置文件
conf/nutch-default.xml 中设置为:

    
      plugin.includes
      protocol-http|urlfilter-(regex|validator)|parse-(html|tika)|index-(basic|anchor)|indexer-solr|scoring-opic|\
      urlnormalizer-(pass|regex|basic)

      Regular expression naming plugin directory names to
      include.  Any plugin not matching this expression is excluded.
      In any case you need at least include the nutch-extensionpoints plugin. By
      default Nutch includes crawling just HTML and plain text via HTTP,
      and basic indexing and search plugins. In order to use HTTPS please enable
      protocol-httpclient, but be aware of possible intermittent problems with the
      underlying commons-httpclient library. Set parsefilter-naivebayes for classification based focused crawler.
     

    

可以看出,indexer-solr 插件已经包含到系统配置中,因此,保持默认配置就好。

    NOTE:
    ---------------------------------------------------------------------------------------------------------------------
    注意 plugin.includes 属性中并没有包含 protocol-httpclient,因此按照属性描述,当前配置应只支持 http 协议,不支持https
    协议的 URL。要使 nutch 支持 https 协议,需要向该属性中添加 protocol-httpclient 插件的支持。但底层的commons-httpclient
    类库不太稳定,可能会发生问题。出于稳定性的目的,暂时不配置 protocol-httpclient 插件支持,以后需要时再来精心设置并测试
    其稳定性。

    但 plugin.includes 属性对 protocol-httpclient 插件的描述并不准确,后面的测试会特意增加一个 https 协议的 URL,以测试
    nutch 的执行结果,并得出相应结论。
    

3.2 配置 URL 种子列表(URL seed list)
-------------------------------------------------------------------------------------------------------------------------
    ● URL 种子列表包含 nutch 要搜索的 web 站点 URL 列表,一行一个 URL。
    ● conf/regex-urlfilter.txt 过滤器文件使用正则表达式来过滤和限定允许 nutch 爬取和下载的的资源类型。


3.2.1 创建 URL 种子列表
-------------------------------------------------------------------------------------------------------------------------
创建一个特定的目录用于存储 URL 列表文件,在该目录下创建一个或多个文本文件,每个文本文件就是一个种子列表文件。编辑文件,向
其中添加要爬取的 web 站点 URL 地址,一行一个 URL。

示例:
    [devalone@nutch nutch]$ pwd
    /opt/nutch/nutch
    [devalone@nutch nutch]$ mkdir -p urls
    [devalone@nutch nutch]$ cd urls

    [devalone@nutch urls]$ vi seed.txt
    [devalone@nutch urls]$ cat seed.txt
    http://news.sohu.com/
    http://mil.sohu.com/
    https://blog.csdn.net/

    
为了验证 https 协议,特意在列表中添加了一个 https 协议的 URL: https://blog.csdn.net/

 

3.2.2 配置正则表达式过滤器(可选的)
-------------------------------------------------------------------------------------------------------------------------
正则表达式过滤器由 conf/regex-urlfilter.txt 文件配置,用于限定 nutch 爬取的资源在可控的范围内。如果失去控制,nutch 很可能
爬取整个互联网的 web 资源,恐怕会耗费几周的时间。

其中任何一个非注释的,非空白的行包含一个正则表达式。

正则表达式以 + 或 - 开始:

    ● + 符号:    表示允许 nutch 爬取的资源。
    ● - 符号:    表示禁止 nutch 爬取的资源。

一个 URL 在此文件中的第一个匹配模式确定了其是包含到爬取列表还是被忽略掉。如果在此文件中没有任何模式匹配,则该 URL 被忽略。

本例限定 nutch 在种子列表中列出的网址范围内爬取,其它网站忽略,因此编辑 conf/regex-urlfilter.txt 文件,注释掉如下的正则表
达式:

    # accept anything else
    # +.

添加如下正则表达式:

    +^https?://(news|mil)\.sohu\.com/
    +^https?://blog\.csdn\.net/


    NOTE:
    ---------------------------------------------------------------------------------------------------------------------
    如果没有在 regex-urlfilter.txt 文件中指定域名,会导致在种子 URL 页面中链接的所有 URL 都会被爬取,数量不可控。
    
    
    
4. 使用单步命令进行全网爬取 (Using Individual Commands for Whole-Web Crawling)
-------------------------------------------------------------------------------------------------------------------------    
全网爬取 (Whole-Web Crawling) 是设计用于在多部机器上运行来处理非常大规模的爬取任务,可能需要几周的时间才能完成。单步命令方
式可以在爬取过程中进行更多的控制,分步骤执行爬取。应该注意,全网爬取并不意味要对整个全球 web 网络进行爬取。可以使用过滤器等
手段对要爬取的 URL 资源列表进行限制,使其限定在一个可控的范围内,将不感兴趣的资源忽略掉,方法如上节所述。


    NOTE:
    ---------------------------------------------------------------------------------------------------------------------
    这类任务耗费资源和时间都非常大,本节只对相关概念进行论述,爬行操作使用上一节配置的小范围 URL 种子列表和过滤器执行。


4.1 分步执行:概念(Step-by-Step: Concepts)
-------------------------------------------------------------------------------------------------------------------------
nutch 数据库由下列部分组成:

① crawl 数据库,或称为 crawldb    :包含 nutch 所了解的每一个 URL 的信息,包括其是否被抓取,以及如果抓取过了,抓取的时间等
    相关信息。
    
② link  数据库, 或称为 linkdb    : 这个数据库包含所有已知的链接 URL,包括源 URL(source URL) 和链接文本。

③ 一系列的段数据(A set of segments): 每一个段数据是一组 URL, 作为一个抓取单元。每个段(segment)是一个目录,其中包含如下
    子目录:

    ● crawl_generate    :包含一组要抓取的 URL,文件类型为 SequenceFile
    ● crawl_fetch        :包含正在抓取的每一个 URL 的状态信息,文件类型为 MapFile
    ● content            :包含从每一个 URL 获取到的原始内容(raw content),文件类型为 MapFile
    ● parse_text        : 包含每一个 URL 解析后的文本,文件类型为 MapFile
    ● parse_data        :包含从每一个 URL 中解析出来的所有外链接(outlinks)和元数据信息,文件类型为 MapFile
    ● crawl_parse        : 包含外链接(outlink) URL, 用于更新 crawldb,文件类型为 SequenceFile    
    
    

4.2 分步执行:将初始 URL 种子列表注入 crawldb (Step-by-Step: Seeding the crawldb with a list of URLs)
-------------------------------------------------------------------------------------------------------------------------
这是分步执行的第一步,使用 injector 命令将 URL 种子列表添加到 crawldb 数据库中。执行这一过程很简单,但也是非常重要的一步。
对于全网爬取的 URL 种子列表,应该精心选择。

传统的 DMOZ 曾经是各种网络爬虫和搜索引擎所青睐的全球 URL 网址列表,但其网站 http://www.dmoz.org/  已于 2017 年 3 月 14 日
永久关闭,不过目前有很多类似的商业化 DMOZ 网站兴起,例如:

    http://www.dmoztools.net
    http://www.dmozdir.org
    http://www.chinadmoz.org
    http://www.webdmoz.org/
    http://www.cdmoz.com/
    ...
    
其中收录了大量的 URL 网址,可以在其中找寻到并获取适用于自己全网爬取任务的 URL 列表,通过直接使用 nutch 程序,或者编写一个
简单的脚本程序,即可获取到某个 DMOZ 网站上收录的所有 URL 来作为 nutch 的初始 URL 种子列表。


4.2.1 引导注入:
-------------------------------------------------------------------------------------------------------------------------
准备好 URL 种子列表之后,可以进行 nutch 爬取的引导注入,命令为 nutch inject。


    NOTE:
    ---------------------------------------------------------------------------------------------------------------------
    nutch 中,执行没有任何命令的 nutch, 获取 nutch 所有命令的简要说明。执行无任何参数和选项的命令获取该命令的用法。
    

命令简要说明:
    inject:inject new urls into the database

命令用法:
    [devalone@nutch nutch]$ bin/nutch inject
    Usage: Injector [-D...] [-overwrite|-update] [-noFilter] [-noNormalize] [-filterNormalizeAll]

           Path to a crawldb directory. If not present, a new one would be created.
           Path to URL file or directory with URL file(s) containing URLs to be injected.
                    A URL file should have one URL per line, optionally followed by custom metadata.
                    Blank lines or lines starting with a '#' would be ignored. Custom metadata must
                    be of form 'key=value' and separated by tabs.
                    Below are reserved metadata keys:

                            nutch.score: A custom score for a url
                            nutch.fetchInterval: A custom fetch interval for a url
                            nutch.fetchInterval.fixed: A custom fetch interval for a url that is not changed by AdaptiveFetchSchedule

                    Example:
                     http://www.apache.org/
                     http://www.nutch.org/ \t nutch.score=10 \t nutch.fetchInterval=2592000 \t userType=open_source

     -overwrite     Overwite existing crawldb records by the injected records. Has precedence over 'update'
     -update        Update existing crawldb records with the injected records. Old metadata is preserved

     -nonormalize   Do not normalize URLs before injecting
     -nofilter      Do not apply URL filters to injected URLs
     -filterNormalizeAll
                    Normalize and filter all URLs including the URLs of existing CrawlDb records

     -D...          set or overwrite configuration property (property=value)
     -Ddb.update.purge.404=true
                    remove URLs with status gone (404) from CrawlDb

    
● 执行 URL 种子注入:

    进入 $NUTCH_INSTALL 目录:

    [devalone@nutch nutch]$ pwd
    /opt/nutch/nutch
    devalone@nutch nutch]$ ll
    drwxr-xr-x  2 devalone devalone     32 6月  29 16:52 bin
    -rw-rw-r--  1 devalone devalone 106848 12月 19 2017 CHANGES.txt
    drwxr-xr-x  2 devalone devalone   4096 7月  21 16:31 conf
    drwxr-xr-x  3 devalone devalone     17 12月 19 2017 docs
    drwxr-xr-x  3 devalone devalone   8192 6月  29 16:52 lib
    -rw-rw-r--  1 devalone devalone 329066 12月 19 2017 LICENSE.txt
    drwxrwxr-x  2 devalone devalone     24 7月  20 18:10 logs
    -rw-rw-r--  1 devalone devalone    427 12月 19 2017 NOTICE.txt
    drwxr-xr-x 71 devalone devalone   4096 12月 19 2017 plugins
    drwxrwxr-x  2 devalone devalone     22 7月  21 16:25 urls

    执行注入:
    [devalone@nutch nutch]$ bin/nutch inject crawl/crawldb urls
    Injector: starting at 2018-07-23 10:50:25
    Injector: crawlDb: crawl/crawldb
    Injector: urlDir: urls
    Injector: Converting injected urls to crawl db entries.
    Injector: overwrite: false
    Injector: update: false
    Injector: Total urls rejected by filters: 0
    Injector: Total urls injected after normalization and filtering: 3
    Injector: Total urls injected but already in CrawlDb: 0
    Injector: Total new urls injected: 3
    Injector: finished at 2018-07-23 10:50:29, elapsed: 00:00:03

    □ 指定 crawldb 目录为当前目录下的 crawl/crawldb (如果不存在,nutch 会自动创建)。
    □ 种子目录为当前目录下之前创建好的 urls (目录内已准备好 URL 种子列表文件,本例为 seed.txt,该目录下可以存在多个种子
    文件或子目录,执行注入时会将该目录及子目录内的种子文件全部注入到 crawldb 中)。


4.2.2 验证注入结果
-------------------------------------------------------------------------------------------------------------------------
注入完成后,查看当前目录下内容:

    [devalone@nutch nutch]$ ll crawl
    总用量 0
    drwxrwxr-x 4 devalone devalone 32 7月  23 10:50 crawldb

crawl/crawldb 目录已创建。

    [devalone@nutch nutch]$ ll crawl/crawldb/
    总用量 0
    drwxrwxr-x 3 devalone devalone 26 7月  23 10:50 current
    drwxrwxr-x 2 devalone devalone  6 7月  23 10:50 old

其下创建了两个子目录:current 和 old。继续探查 current 目录:

    [devalone@nutch nutch]$ ll crawl/crawldb/current/
    总用量 0
    drwxrwxr-x 2 devalone devalone 66 7月  23 10:50 part-r-00000
    [devalone@nutch nutch]$ ll crawl/crawldb/current/part-r-00000/
    总用量 8
    -rw-r--r-- 1 devalone devalone 263 7月  23 10:50 data
    -rw-r--r-- 1 devalone devalone 213 7月  23 10:50 index

已创建实际的数据文件 data 和索引文件 index,并且文件非空,说明数据已注入到数据库中,状态良好。

如果要进一步验证数据库中的数据,可以使用 readdb 命令,示例如下:

    [devalone@nutch nutch]$  bin/nutch readdb crawl/crawldb -dump crawldb-dump
    CrawlDb dump: starting
    CrawlDb db: crawl/crawldb
    CrawlDb dump: done

    [devalone@nutch nutch]$ ll crawldb-dump/
    总用量 4
    -rw-r--r-- 1 devalone devalone 744 7月  23 11:10 part-00000
    [devalone@nutch nutch]$ cat crawldb-dump/part-00000
    http://mil.sohu.com/    Version: 7
    Status: 1 (db_unfetched)
    Fetch time: Mon Jul 23 10:50:25 CST 2018
    Modified time: Thu Jan 01 08:00:00 CST 1970
    Retries since fetch: 0
    Retry interval: 2592000 seconds (30 days)
    Score: 1.0
    Signature: null
    Metadata:

    http://news.sohu.com/   Version: 7
    Status: 1 (db_unfetched)
    Fetch time: Mon Jul 23 10:50:25 CST 2018
    Modified time: Thu Jan 01 08:00:00 CST 1970
    Retries since fetch: 0
    Retry interval: 2592000 seconds (30 days)
    Score: 1.0
    Signature: null
    Metadata:

    https://blog.csdn.net/  Version: 7
    Status: 1 (db_unfetched)
    Fetch time: Mon Jul 23 10:50:25 CST 2018
    Modified time: Thu Jan 01 08:00:00 CST 1970
    Retries since fetch: 0
    Retry interval: 2592000 seconds (30 days)
    Score: 1.0
    Signature: null
    Metadata:

3 个初始种子 URL 存在于数据库中,状态良好。

 
4.3 分步执行:抓取 (Step-by-Step: Fetching)
-------------------------------------------------------------------------------------------------------------------------


4.3.1 生成抓取列表
-------------------------------------------------------------------------------------------------------------------------
要执行抓取操作,首先要从爬取数据库中生成抓取列表,命令为 nutch generate

命令简要说明:
    generate:generate new segments to fetch from crawl db

命令用法:
    Usage: Generator [-force] [-topN N] [-numFetchers numFetchers] [-expr ] \
    [-adddays ] [-noFilter] [-noNorm] [-maxNumSegments ]

生成抓取列表:
    [devalone@nutch nutch]$ bin/nutch generate crawl/crawldb crawl/segments
    Generator: starting at 2018-07-23 11:31:13
    Generator: Selecting best-scoring urls due for fetch.
    Generator: filtering: true
    Generator: normalizing: true
    Generator: running in local mode, generating exactly one partition.
    Generator: Partitioning selected urls for politeness.
    Generator: segment: crawl/segments/20180723113116
    Generator: finished at 2018-07-23 11:31:17, elapsed: 00:00:04

    [devalone@nutch nutch]$ ll crawl
    总用量 0
    drwxrwxr-x 4 devalone devalone 32 7月  23 11:31 crawldb
    drwxrwxr-x 3 devalone devalone 28 7月  23 11:31 segments

    [devalone@nutch nutch]$ ll crawl/segments/
    总用量 0
    drwxrwxr-x 3 devalone devalone 28 7月  23 11:31 20180723113116

为所有要抓取的页面生成了一个抓取列表(a fetch list)。抓取列表位于新创建的段目录(segment directory)内。段目录是按创建时间命
名的,我们将这个段名保存到 shell 变量 s1 中,以方便后续使用:

    [devalone@nutch nutch]$ s1=`ls -d crawl/segments/2* | tail -1`
    [devalone@nutch nutch]$ echo $s1
    crawl/segments/20180723113116


4.3.2 执行抓取任务
-------------------------------------------------------------------------------------------------------------------------
执行页面抓取任务的命令是 nutch fetch。

命令简要说明:
    fetch: fetch a segment's pages

命令用法:
    Usage: Fetcher [-threads n]

执行抓取任务: 将环境变量中存储的段名作为参数传递给 fetch 命令,采用默认线程数量
    [devalone@nutch nutch]$ bin/nutch fetch $s1
    Fetcher: starting at 2018-07-23 11:53:50
    Fetcher: segment: crawl/segments/20180723113116
    Fetcher: threads: 10
    Fetcher: time-out divisor: 2
    ...

    Fetcher: finished at 2018-07-23 11:53:54, elapsed: 00:00:03

抓取完毕。从输出中可以看出,默认的抓取线程数量为 10。


4.3.3 执行解析任务
-------------------------------------------------------------------------------------------------------------------------
抓取到的页面需要进行解析才能存储到数据库中。执行解析的命令为 nutch parse。

命令简要说明:
    parse:    parse a segment's pages

命令用法:
    Usage: ParseSegment segment [-noFilter] [-noNormalize]

执行解析任务:将段名作为参数传递给 parse 命令:
    [devalone@nutch nutch]$ nutch parse $s1
    ParseSegment: starting at 2018-07-23 12:06:29
    ParseSegment: segment: crawl/segments/20180723113116
    Parsed (234ms):http://mil.sohu.com/
    Parsed (46ms):http://news.sohu.com/
    Parsed (35ms):https://blog.csdn.net/
    ParseSegment: finished at 2018-07-23 12:06:31, elapsed: 00:00:01

3 个抓取到的页面解析完成。


4.3.4 更新 crawldb 数据库
-------------------------------------------------------------------------------------------------------------------------
解析任务完成后,将抓取结果更新到 crawldb 数据库,这是爬取循环的最后一步。更新数据库的命令为 nutch updatedb.

命令简要说明:
    updatedb: update crawl db from segments after fetching

命令用法:
        Usage: CrawlDb (-dir | ...) [-force] [-normalize] [-filter] [-noAdditions]
        crawldb CrawlDb to update
        -dir segments   parent directory containing all segments to update from
        seg1 seg2 ...   list of segment names to update from
        -force  force update even if CrawlDb appears to be locked (CAUTION advised)
        -normalize      use URLNormalizer on urls in CrawlDb and segment (usually not needed)
        -filter use URLFilters on urls in CrawlDb and segment
        -noAdditions    only update already existing URLs, don't add any newly discovered URLs


更新 crawldb 数据库: 将 crawldb 目录和段名作为参数传递给 updatedb 命令

    [devalone@nutch nutch]$ nutch updatedb crawl/crawldb $s1
    CrawlDb update: starting at 2018-07-23 12:15:17
    CrawlDb update: db: crawl/crawldb
    CrawlDb update: segments: [crawl/segments/20180723113116]
    CrawlDb update: additions allowed: true
    CrawlDb update: URL normalizing: false
    CrawlDb update: URL filtering: false
    CrawlDb update: 404 purging: false
    CrawlDb update: Merging segment data into db.
    CrawlDb update: finished at 2018-07-23 12:15:20, elapsed: 00:00:02

更新完成。现在 crawldb 数据库中含有所有最初的种子 URL 列表页面更新后的信息,以及从初始 URL 页面中新发现的链接信息。通过
readdb 命令简单查看下数据库中的内容(如果使用已存在的目录作为输出目录,需要先将其删除,否则报错,这是所有 hadoop 相关项目
的共性):

    [devalone@nutch nutch]$ rm -rf crawldb-dump/
    [devalone@nutch nutch]$  bin/nutch readdb crawl/crawldb -dump crawldb-dump
    CrawlDb dump: starting
    CrawlDb db: crawl/crawldb
    CrawlDb dump: done
    
    [devalone@nutch nutch]$ ll
    [devalone@nutch nutch]$ ll crawldb-dump/
    总用量 16
    -rw-r--r-- 1 devalone devalone 15862 7月  23 12:22 part-00000
    
    [devalone@nutch nutch]$ cat crawldb-dump/part-00000
    http://mil.sohu.com/    Version: 7
    Status: 2 (db_fetched)
    Fetch time: Wed Aug 22 11:53:53 CST 2018
    Modified time: Mon Jul 23 11:53:53 CST 2018
    Retries since fetch: 0
    Retry interval: 2592000 seconds (30 days)
    Score: 1.75
    Signature: 89f36893e295bc0b08f1b1e36bb0c49d
    Metadata:
            _pst_=success(1), lastModified=0
            _rs_=16
            Content-Type=text/html
            nutch.protocol.code=200

    http://mil.sohu.com/1468        Version: 7
    Status: 1 (db_unfetched)
    Fetch time: Mon Jul 23 12:15:19 CST 2018
    Modified time: Thu Jan 01 08:00:00 CST 1970
    Retries since fetch: 0
    Retry interval: 2592000 seconds (30 days)
    Score: 0.16666667
    Signature: null
    Metadata:

    http://mil.sohu.com/1469        Version: 7
    Status: 1 (db_unfetched)
    Fetch time: Mon Jul 23 12:15:19 CST 2018
    Modified time: Thu Jan 01 08:00:00 CST 1970
    Retries since fetch: 0
    Retry interval: 2592000 seconds (30 days)
    Score: 0.16666667
    Signature: null
    Metadata:

    ...
        
可以发现,数据库中的内容比之前的只有 3 条记录多出很多。可以使用 readdb 的 -stats 选项查看数据库的统计信息:

    [devalone@nutch nutch]$  bin/nutch readdb crawl/crawldb -stats
    CrawlDb statistics start: crawl/crawldb
    Statistics for CrawlDb: crawl/crawldb
    TOTAL urls:     57
    shortest fetch interval:        30 days, 00:00:00
    avg fetch interval:     30 days, 00:00:00
    longest fetch interval: 30 days, 00:00:00
    earliest fetch time:    Mon Jul 23 12:15:00 CST 2018
    avg of fetch times:     Wed Jul 25 02:07:00 CST 2018
    latest fetch time:      Wed Aug 22 11:53:00 CST 2018
    retry 0:        57
    score quantile 0.01:    0.010204081423580647
    score quantile 0.05:    0.010204081423580647
    score quantile 0.1:     0.010204081423580647
    score quantile 0.2:     0.010204081423580647
    score quantile 0.25:    0.010204081423580647
    score quantile 0.3:     0.016326530277729012
    score quantile 0.4:     0.020408162847161293
    score quantile 0.5:     0.020408162847161293
    score quantile 0.6:     0.030612245202064514
    score quantile 0.7:     0.030612245202064514
    score quantile 0.75:    0.030612245202064514
    score quantile 0.8:     0.0346938773989678
    score quantile 0.9:     0.1666666716337204
    score quantile 0.95:    0.750765299797057
    score quantile 0.99:    1.7033333361148832
    min score:      0.010204081423580647
    avg score:      0.10526320808812191
    max score:      1.75
    status 1 (db_unfetched):        54
    status 2 (db_fetched):  3
    CrawlDb statistics: done

可以看出,当前 crawldb 中共有 57 个 URL,其中 3 个状态为 status 2 (db_fetched),即最初的种子列表中的 3 URL 已经抓取完毕。
有 54 个 URL状态为 status 1 (db_unfetched),是从最初的 3 个 URL页面中新发现的连接,还没有执行页面抓取,处于 db_unfetched
状态。


4.3.5 执行第二次次抓取过程
-------------------------------------------------------------------------------------------------------------------------
为了获取足够多的测试数据,再次执行抓取过程,这次生成并抓取包含评分前 1000(top-scoring 1000) 的页面:其实当前数据库中只有
54 个未抓取的页面,这个选项在当前数据库中执行生成段的操作并未起作用,加上也无妨。

    [devalone@nutch nutch]$ nutch generate crawl/crawldb crawl/segments -topN 1000

    [devalone@nutch nutch]$ s2=`ls -d crawl/segments/2* | tail -1`
    [devalone@nutch nutch]$ echo $s2
    crawl/segments/20180723124830

    [devalone@nutch nutch]$ nutch fetch $s2
    Fetcher: starting at 2018-07-23 12:50:27
    Fetcher: segment: crawl/segments/20180723124830
    Fetcher: threads: 10

    ...
    Fetcher: finished at 2018-07-23 12:54:37, elapsed: 00:04:10
    
    用时 00:04:10

    [devalone@nutch nutch]$ nutch parse $s2
    [devalone@nutch nutch]$ nutch updatedb crawl/crawldb $s2
    
查看数据库状态:
    [devalone@nutch nutch]$  bin/nutch readdb crawl/crawldb -stats
    CrawlDb statistics start: crawl/crawldb
    Statistics for CrawlDb: crawl/crawldb
    TOTAL urls:     1361
    shortest fetch interval:        30 days, 00:00:00
    avg fetch interval:     30 days, 00:15:52
    longest fetch interval: 45 days, 00:00:00
    earliest fetch time:    Mon Jul 23 12:57:00 CST 2018
    avg of fetch times:     Tue Jul 24 18:51:00 CST 2018
    latest fetch time:      Thu Sep 06 12:50:00 CST 2018
    retry 0:        1360
    retry 1:        1
    score quantile 0.01:    1.6222300565069806E-4
    score quantile 0.05:    2.0923737523844465E-4
    score quantile 0.1:     2.170994079538754E-4
    score quantile 0.2:     3.1386775372084226E-4
    score quantile 0.25:    3.2318823286914267E-4
    score quantile 0.3:     3.3286939081000655E-4
    score quantile 0.4:     4.436204064404592E-4
    score quantile 0.5:     6.01460276577141E-4
    score quantile 0.6:     6.462093988934962E-4
    score quantile 0.7:     8.13645781966409E-4
    score quantile 0.75:    9.000660493791871E-4
    score quantile 0.8:     9.7666619066149E-4
    score quantile 0.9:     0.0013502709909944855
    score quantile 0.95:    0.0023547878954559565
    score quantile 0.99:    0.03270121983119422
    min score:      1.0855405707843602E-4
    avg score:      0.005894269950244464
    max score:      1.8964647054672241
    status 1 (db_unfetched):        1305
    status 2 (db_fetched):  55
    status 3 (db_gone):     1
    CrawlDb statistics: done

URL 总数已增加到 1361 个,其中有 55 个已抓取,1305 个新发现的链接未抓取,1 个处于 status 3 (db_gone) 状态。


4.3.6 执行第三次抓取过程
-------------------------------------------------------------------------------------------------------------------------
数据库中有 1305 个未抓取的 URL, 这里的 -topN 1000 会起作用,限制其生成评分前 1000 个 URL 的段信息。

    [devalone@nutch nutch]$ nutch generate crawl/crawldb crawl/segments -topN 1000
    [devalone@nutch nutch]$ ll crawl/segments/
    总用量 0
    drwxrwxr-x 8 devalone devalone 117 7月  23 12:06 20180723113116
    drwxrwxr-x 8 devalone devalone 117 7月  23 12:56 20180723124830
    drwxrwxr-x 3 devalone devalone  28 7月  23 13:04 20180723130401
    [devalone@nutch nutch]$ s3=`ls -d crawl/segments/2* | tail -1`
    [devalone@nutch nutch]$ echo $s3
    crawl/segments/20180723130401

    [devalone@nutch nutch]$ nutch fetch $s3
    Fetcher: starting at 2018-07-23 13:06:07
    Fetcher: segment: crawl/segments/20180723130401
    Fetcher: threads: 10
    ...

    Fetcher: finished at 2018-07-23 14:32:43, elapsed: 01:26:36

此次抓取用时 01:26:36

    NOTE:
    ---------------------------------------------------------------------------------------------------------------------
    对于这种耗时的操作,可以联合 nohup 命令来执行,示例:
        
        [devalone@nutch nutch]$ nohup nutch fetch $s3 &

        
    [devalone@nutch nutch]$ nutch parse $s3
    [devalone@nutch nutch]$ nutch updatedb crawl/crawldb $s3
    
    [devalone@nutch nutch]$ nutch readdb crawl/crawldb -stats
    CrawlDb statistics start: crawl/crawldb
    Statistics for CrawlDb: crawl/crawldb
    TOTAL urls:     18442
    shortest fetch interval:        30 days, 00:00:00
    avg fetch interval:     30 days, 00:01:10
    longest fetch interval: 45 days, 00:00:00
    earliest fetch time:    Mon Jul 23 12:57:00 CST 2018
    avg of fetch times:     Wed Jul 25 07:35:00 CST 2018
    latest fetch time:      Thu Sep 06 12:50:00 CST 2018
    retry 0:        18433
    retry 1:        9
    score quantile 0.01:    3.363983068993548E-6
    score quantile 0.05:    4.0650803027780635E-6
    score quantile 0.1:     5.252996839943921E-6
    score quantile 0.2:     8.687948599238534E-6
    score quantile 0.25:    1.0351363643525419E-5
    score quantile 0.3:     1.1638136404260567E-5
    score quantile 0.4:     1.5087516350721173E-5
    score quantile 0.5:     1.956822216838666E-5
    score quantile 0.6:     2.4080784436340625E-5
    score quantile 0.7:     2.9829692724346616E-5
    score quantile 0.75:    3.42503072351974E-5
    score quantile 0.8:     4.092971121440248E-5
    score quantile 0.9:     8.750581586759325E-5
    score quantile 0.95:    4.3720556372452434E-4
    score quantile 0.99:    0.001597540448419741
    min score:      0.0
    avg score:      4.8001176325052655E-4
    max score:      1.8964647054672241
    status 1 (db_unfetched):        17394
    status 2 (db_fetched):  1039
    status 3 (db_gone):     1
    status 4 (db_redir_temp):       2
    status 5 (db_redir_perm):       6
    CrawlDb statistics: done

URL 总数已增加到 18442 个,其中有 1039 个已抓取,17394 个新发现的链接未抓取,1 个处于 status 3 (db_gone) 状态。

 

■ 验证 nutch 是否抓取了 https 协议的 URL 页面
-------------------------------------------------------------------------------------------------------------------------
dump 出状态为 db_fetched 的 URL:

    [devalone@nutch nutch]$ nutch readdb crawl/crawldb/ -dump crawldb-dump -status db_fetched
    CrawlDb dump: starting
    CrawlDb db: crawl/crawldb/
    CrawlDb dump: done

    [devalone@nutch nutch]$ ll crawldb-dump/part-00000
    -rw-r--r-- 1 devalone devalone 437326 7月  24 16:12 crawldb-dump/part-00000

查看 dump 出的数据库内容:
    [devalone@nutch nutch]$ cat crawldb-dump/part-00000
    https://blog.csdn.net/10km/article/details/81147355     Version: 7
    Status: 2 (db_fetched)
    Fetch time: Wed Aug 22 13:32:49 CST 2018
    Modified time: Mon Jul 23 13:32:49 CST 2018
    Retries since fetch: 0
    Retry interval: 2592000 seconds (30 days)
    Score: 6.664876E-4
    Signature: b59a0e8cd511f1090489db04f3518a2b
    Metadata:
            _pst_=success(1), lastModified=1531722549000
            _rs_=147
            Content-Type=text/html
            nutch.protocol.code=200

    https://blog.csdn.net/A_B_C_D_E______/article/details/81142260  Version: 7
    Status: 2 (db_fetched)
    Fetch time: Wed Aug 22 13:11:52 CST 2018
    Modified time: Mon Jul 23 13:11:52 CST 2018
    Retries since fetch: 0
    Retry interval: 2592000 seconds (30 days)
    Score: 3.4539928E-4
    Signature: 97a758b6c2f999204168cbc817dd1a88
    Metadata:
            _pst_=success(1), lastModified=1531722549000
            _rs_=156
            Content-Type=text/html
            nutch.protocol.code=200

    https://blog.csdn.net/Ancony_/article/details/81141073  Version: 7
    Status: 2 (db_fetched)
    Fetch time: Wed Aug 22 14:17:03 CST 2018
    Modified time: Mon Jul 23 14:17:03 CST 2018
    Retries since fetch: 0
    Retry interval: 2592000 seconds (30 days)
    Score: 3.4383315E-4
    Signature: f9050a1c2ff299c7313d052114a4115d
    Metadata:
            _pst_=success(1), lastModified=1531722549000
            _rs_=175
            Content-Type=text/html
            nutch.protocol.code=200

    ...
    
可以看出,数据库中含有相当一部分已抓取到的 https 协议的 URL,说明默认的 plugin.includes 属性设置可以处理 http 和 https
协议的 URL,不需要进一步包含 protocol-httpclient。


    ● NOTE:
    ---------------------------------------------------------------------------------------------------------------------
    事实上,plugin.includes 的属性值是一个正则表达式,该属性在默认配置文件nutch-default.xml 中设置为:
    
    
      plugin.includes
      protocol-http|urlfilter-(regex|validator)|parse-(html|tika)|index-(basic|anchor)|indexer-solr|scoring-opic|\
      urlnormalizer-(pass|regex|basic)

      Regular expression naming plugin directory names to
      include.  Any plugin not matching this expression is excluded.
      In any case you need at least include the nutch-extensionpoints plugin. By
      default Nutch includes crawling just HTML and plain text via HTTP,
      and basic indexing and search plugins. In order to use HTTPS please enable
      protocol-httpclient, but be aware of possible intermittent problems with the
      underlying commons-httpclient library. Set parsefilter-naivebayes for classification based focused crawler.
     

    

    
      
    其中 protocol-http| 部分已经包含了对 protocol-httpclient 字符串的匹配。因此,默认情况下,nutch 能够直接载入并使用
    protocol-httpclient 插件来处理 https 协议, 只是该属性的描述( 元素内容) 对 protocol-httpclient 插件的说明
    令人困惑。这应该是以前版本遗留下来的一个文档 bug,除了会给使用者造成困惑之外,不会影响 nutch 的执行,因此不必理会。

 
 
 
4.4 分步执行: 消除重复 URL (Step-by-Step: Deleting Duplicates)
-------------------------------------------------------------------------------------------------------------------------
完成数据抓取任务之后,需要解决重复 URL 的问题,以确保 crawldb 数据库中 URL 的唯一性,这样就保证了建立索引时 URL 是唯一的。
                    
消除重复 URL 使用 nutch dedup 命令。

命令简要说明:
    
    dedup:deduplicate entries in the crawldb and give them a special status
    

详细描述:
-------------------------------------------------------------------------------------------------------------------------
The dedup command is an alias for the class org.apache.nutch.crawl.DeduplicationJob and is available since Nutch 1.8 (Not
yet in Nutch 2.x as of May 2014,即截止 2014 年5月,Nutch 2.x 中还没有 dedup 命令).

This command takes a path to a crawldb as parameter and finds duplicates based on the signature. If several entries share
the same signature, the one with the highest score is kept. If the scores are the same, then the fetch time is used to
determine which one to keep with the most recent one being kept. If their fetch times are the same we keep the one with the
shortest URL. The entries which are not kept have their status changed to STATUS_DB_DUPLICATE, this is then used by the
Cleaning and Indexing jobs to delete the corresponding documents in the backends (SOLR, Elasticsearch).

The dedup command replaces the SOLR dedup command which was limited to SOLR and was a lot less efficient.

dedup 命令从 Nutch 1.8 开始替换 SOLR dedup 命令,用法上也有所不同。应该在建立 Solr 索引之前执行,以保证 URL在 crawldb 数据
库和 Solr 索引中的唯一性。

命令用法:
    Usage: DeduplicationJob [-group ] [-compareOrder ,,]
    
    
消除重复:

    [devalone@nutch nutch]$ nutch dedup crawl/crawldb
    DeduplicationJob: starting at 2018-07-24 12:10:16
    Deduplication: 1 documents marked as duplicates
    Deduplication: Updating status of duplicate urls into crawl db.
    Deduplication finished at 2018-07-24 12:10:22, elapsed: 00:00:05

查看 crawldb 数据库此时的状态:
    [devalone@nutch nutch]$ nutch readdb crawl/crawldb -stats
    CrawlDb statistics start: crawl/crawldb
    Statistics for CrawlDb: crawl/crawldb
    TOTAL urls:     18442
    shortest fetch interval:        30 days, 00:00:00
    avg fetch interval:     30 days, 00:01:10
    longest fetch interval: 45 days, 00:00:00
    earliest fetch time:    Mon Jul 23 12:57:00 CST 2018
    avg of fetch times:     Wed Jul 25 07:35:00 CST 2018
    latest fetch time:      Thu Sep 06 12:50:00 CST 2018
    retry 0:        18433
    retry 1:        9
    score quantile 0.01:    3.363983068993548E-6
    score quantile 0.05:    4.0650803027780635E-6
    score quantile 0.1:     5.252996839943921E-6
    score quantile 0.2:     8.687948599238534E-6
    score quantile 0.25:    1.0351363643525419E-5
    score quantile 0.3:     1.1638136404260567E-5
    score quantile 0.4:     1.5087516350721173E-5
    score quantile 0.5:     1.956822216838666E-5
    score quantile 0.6:     2.4080784436340625E-5
    score quantile 0.7:     2.9829692724346616E-5
    score quantile 0.75:    3.42503072351974E-5
    score quantile 0.8:     4.092971121440248E-5
    score quantile 0.9:     8.750581586759325E-5
    score quantile 0.95:    4.3720556372452434E-4
    score quantile 0.99:    0.001597540448419741
    min score:      0.0
    avg score:      4.8001176325052655E-4
    max score:      1.8964647054672241
    status 1 (db_unfetched):        17394
    status 2 (db_fetched):  1038
    status 3 (db_gone):     1
    status 4 (db_redir_temp):       2
    status 5 (db_redir_perm):       6
    status 7 (db_duplicate):        1
    CrawlDb statistics: done

此时已抓取的 URL 变为 1038 个,出现 1 个重复的 URL:    status 7 (db_duplicate)。

 

4.5 分步执行:反转链接 (Step-by-Step: Invertlinks)
-------------------------------------------------------------------------------------------------------------------------
在建立索引之前,首先需要反转所有的链接,这样才能为页面的锚点文本建立索引。反转链接使用命令 invertlinks 。


命令简要说明:
    invertlinks:create a linkdb from parsed segments
    
命令用法:
        Usage: LinkDb (-dir | ...) [-force] [-noNormalize] [-noFilter]
        linkdb  output LinkDb to create or update
        -dir segmentsDir        parent directory of several segments, OR
        seg1 seg2 ...    list of segment directories
        -force  force update even if LinkDb appears to be locked (CAUTION advised)
        -noNormalize    don't normalize link URLs
        -noFilter       don't apply URLFilters to link URLs

反转链接: 指定链接数据库为 crawl/linkdb,段目录为 crawl/segments

    [devalone@nutch nutch]$ nutch invertlinks crawl/linkdb -dir crawl/segments
    LinkDb: starting at 2018-07-23 15:19:10
    LinkDb: linkdb: crawl/linkdb
    LinkDb: URL normalize: true
    LinkDb: URL filter: true
    LinkDb: internal links will be ignored.
    LinkDb: adding segment: file:/opt/nutch/apache-nutch-1.14/crawl/segments/20180723113116
    LinkDb: adding segment: file:/opt/nutch/apache-nutch-1.14/crawl/segments/20180723124830
    LinkDb: adding segment: file:/opt/nutch/apache-nutch-1.14/crawl/segments/20180723130401
    LinkDb: finished at 2018-07-23 15:19:13, elapsed: 00:00:02


4.6 分步执行:为 Apache Solr 建立索引 (Step-by-Step: Indexing into Apache Solr)
-------------------------------------------------------------------------------------------------------------------------
在执行这一步之前,应该安装好 Solr。


    NOTE:
    ---------------------------------------------------------------------------------------------------------------------
    后面第 6 节会讨论 Apache Solr 的安装过程,现在假设已经安装完毕。

 

为 Apache Solr 建立索引使用 index 命令

命令简要说明:
    index: run the plugin-based indexer on parsed segments and linkdb

命令用法:
    Usage: Indexer [-linkdb ] [-params k1=v1&k2=v2...] ( ... | -dir ) [-noCommit]\
    [-del    eteGone] [-filter] [-normalize] [-addBinaryContent] [-base64]
    Active IndexWriters :
    SOLRIndexWriter
            solr.server.url : URL of the SOLR instance
            solr.zookeeper.hosts : URL of the Zookeeper quorum
            solr.commit.size : buffer size when sending to SOLR (default 1000)
            solr.mapping.file : name of the mapping file for fields (default solrindex-mapping.xml)
            solr.auth : use authentication (default false)
            solr.auth.username : username for authentication
            solr.auth.password : password for authentication
            

建立索引: 将 Solr server URL 以 Java 参数 -D key=value 的形式传递给 index 命令:

    -Dsolr.server.url=http://localhost:8983/solr/nutch


执行过程如下所示:
-------------------------------------------------------------------------------------------------------------------------
    [devalone@nutch nutch]$ bin/nutch index -Dsolr.server.url=http://localhost:8983/solr/nutch crawl/crawldb -linkdb \
    crawl/linkdb -dir crawl/segments/ -filter -normalize -deleteGone

    Segment dir is complete: file:/opt/nutch/apache-nutch-1.14/crawl/segments/20180723113116.
    Segment dir is complete: file:/opt/nutch/apache-nutch-1.14/crawl/segments/20180723124830.
    Segment dir is complete: file:/opt/nutch/apache-nutch-1.14/crawl/segments/20180723130401.
    Indexer: starting at 2018-07-23 17:56:53
    Indexer: deleting gone documents: true
    Indexer: URL filtering: true
    Indexer: URL normalizing: true
    Active IndexWriters :
    SOLRIndexWriter
            solr.server.url : URL of the SOLR instance
            solr.zookeeper.hosts : URL of the Zookeeper quorum
            solr.commit.size : buffer size when sending to SOLR (default 1000)
            solr.mapping.file : name of the mapping file for fields (default solrindex-mapping.xml)
            solr.auth : use authentication (default false)
            solr.auth.username : username for authentication
            solr.auth.password : password for authentication


    Indexing 250/250 documents
    Deleting 0 documents
    SolrIndexer: deleting 1/1 documents
    Indexing 250/500 documents
    Deleting 0 documents
    Indexing 250/750 documents
    Deleting 0 documents
    SolrIndexer: deleting 4/5 documents
    Indexing 250/1000 documents
    Deleting 0 documents
    SolrIndexer: deleting 4/9 documents
    Indexing 27/1027 documents
    Deleting 0 documents
    Indexer: number of documents indexed, deleted, or skipped:
    Indexer:      1  deleted (gone)
    Indexer:      8  deleted (redirects)
    Indexer:   1027  indexed (add/update)
    Indexer: finished at 2018-07-23 17:57:14, elapsed: 00:00:21

索引建立完成之后,可以通过如下链接执行搜索:

    http://localhost:8983/solr/#/nutch/query

或通过域名访问:
    http://nutch.sansovo.org:8983/solr/#/nutch/query

 

4.7 分步执行:清理 Solr (Step-by-Step: Cleaning Solr)
-------------------------------------------------------------------------------------------------------------------------
单步执行的最后一步,是对 crawldb 和 Solr 索引进行清理。这也是在更新 crawldb 之后经常做的操作。清理使用 nutch clean 命令。

命令简要说明:

    clean :remove HTTP 301 and 404 documents and duplicates from indexing backends configured via plugins

命令用法:
    Usage: CleaningJob [-noCommit]
    Active IndexWriters :
    SOLRIndexWriter
            solr.server.url : URL of the SOLR instance
            solr.zookeeper.hosts : URL of the Zookeeper quorum
            solr.commit.size : buffer size when sending to SOLR (default 1000)
            solr.mapping.file : name of the mapping file for fields (default solrindex-mapping.xml)
            solr.auth : use authentication (default false)
            solr.auth.username : username for authentication
            solr.auth.password : password for authentication

执行 clean 命令的 Java class 是 CleaningJob 。该类扫描整个 crawldb 目录查找状态为 DB_GONE (404/301) 的 URL 条目,并向 Solr
发送删除请求。Solr 收到上述请求之后,及时删除这些文档。如此维护了 Solr 索引的健康质量。

清理 Solr:
    [devalone@nutch nutch]$ nutch clean crawl/crawldb -Dsolr.server.url=http://nutch.sansovo.org:8983/solr/nutch
    SolrIndexer: deleting 2/2 documents
    SolrIndexer: deleting 2/2 documents
    ...
    


5. 使用 crawl 脚本 (Using the crawl script)
-------------------------------------------------------------------------------------------------------------------------
crawl 脚本集成了上述单步执行的各个步骤,在一个可执行脚本中执行各步骤的命令。即在爬取过程中反复执行如下过程:

     inject->generate->fetch->parse->updatedb

对于非全网的小规模爬取,完全可以使用 crawl 命令完成整个任务。


命令用法:
    Usage: crawl [-i|--index] [-D "key=value"] [-w|--wait] [-s ]
            -i|--index      Indexes crawl results into a configured indexer
            -D              A Java property to pass to Nutch calls
            -w|--wait       NUMBER[SUFFIX] Time to wait before generating a new segment when no URLs
                            are scheduled for fetching. Suffix can be: s for second,
                            m for minute, h for hour and d for day. If no suffix is
                            specified second is used by default.
            -s Seed Dir     Path to seeds file(s)
            Crawl Dir       Directory where the crawl/link/segments dirs are saved
            Num Rounds      The number of rounds to run this crawl for

其中最后一个参数 迭代次数是一个数字,用于指定执行爬取过程的迭代次数。数字越大执行爬取过程次数越多,抓取 URL
页面也就越多,抓取深度和广度更加庞大,耗费的资源和时间呈几何数量增长。因此在测试环境中不宜设得过大,2~3 次就可以了。


5.1 准备测试环境
-------------------------------------------------------------------------------------------------------------------------
为了有一个干净的测试环境,指定 为新的 testcrawl 目录。为 solr 创建一个不同的 core, 名称为 crawl:


    [devalone@nutch solr]$ cd server/solr/configsets/
    [devalone@nutch configsets]$ cp -r nutch crawl
    [devalone@nutch solr]$ ll
    总用量 12
    drwxr-xr-x 7 devalone devalone  122 7月  24 14:05 configsets
    drwxrwxr-x 2 devalone devalone    6 7月  24 14:03 crawl
    drwxrwxr-x 4 devalone devalone   53 7月  23 17:19 nutch
    -rw-r--r-- 1 devalone devalone 3037 5月  18 17:59 README.txt
    -rw-r--r-- 1 devalone devalone 2117 2月  22 05:53 solr.xml
    -rw-r--r-- 1 devalone devalone  975 2月  22 05:53 zoo.cfg
                
    [devalone@nutch solr]$ cd $SOLR_INSTALL

做一次删除操作,清理环境:
    [devalone@nutch solr]$ solr delete -c crawl

    Deleting core 'crawl' using command:
    http://localhost:8983/solr/admin/cores?action=UNLOAD&core=crawl&deleteIndex=true&deleteDataDir=true&deleteInstanceDir=true

    {"responseHeader":{
        "status":0,
        "QTime":9}}

    
创建 crawl core:
    [devalone@nutch solr]$ bin/solr create -c crawl -d server/solr/configsets/crawl/conf/

    Copying configuration to new core instance directory:
    /opt/solr/solr/server/solr/crawl

    Creating new core 'crawl' using command:
    http://localhost:8983/solr/admin/cores?action=CREATE&name=crawl&instanceDir=crawl

    {
      "responseHeader":{
        "status":0,
        "QTime":387},
      "core":"crawl"}
        
访问链接 http://nutch.sansovo.org:8983/solr/#/crawl/query 执行查询任务,应该返回空,因为新创建的 crawl core还没有建立索引。

得到 Solr server URL:

    -Dsolr.server.url=http://localhost:8983/solr/crawl/
    或:
    -Dsolr.server.url=http://nutch.sansovo.org:8983/solr/crawl/

    
    
5.2 运行 crawl 脚本
-------------------------------------------------------------------------------------------------------------------------
依然使用之前定义的种子文件 urls/seed.txt,设置迭代次数 为 3 。

由于运行时间可能会比较长,使用 nohup 命令来执行 crawl 脚本:

[devalone@nutch nutch]$ nohup crawl -i -D solr.server.url=http://nutch.sansovo.org:8983/solr/crawl/ -s urls/ testcrawl 3 &
[1] 16512
[devalone@nutch nutch]$ nohup: 忽略输入并把输出追加到"nohup.out"

nohup 进入后台运行,并将屏幕输出追加到当前目录下的 nohup.out 文件:

    [devalone@nutch nutch]$ ll nohup.out
    -rw------- 1 devalone devalone 21470 7月  24 14:36 nohup.out
    [devalone@nutch nutch]$ ll nohup.out
    -rw------- 1 devalone devalone 65054 7月  24 14:41 nohup.out
    
可以看到 nohup.out 日志文件持续增加。

查看最新执行信息:
    [devalone@nutch nutch]$ tail nohup.out
    -activeThreads=50, spinWaiting=50, fetchQueues.totalSize=815, fetchQueues.getQueueCount=1
    FetcherThread 48 fetching https://blog.csdn.net/X8i0Bev/article/details/81091490 (queue crawl delay=5000ms)
    -activeThreads=50, spinWaiting=50, fetchQueues.totalSize=814, fetchQueues.getQueueCount=1
    -activeThreads=50, spinWaiting=50, fetchQueues.totalSize=814, fetchQueues.getQueueCount=1
    -activeThreads=50, spinWaiting=50, fetchQueues.totalSize=814, fetchQueues.getQueueCount=1
    -activeThreads=50, spinWaiting=50, fetchQueues.totalSize=814, fetchQueues.getQueueCount=1
    -activeThreads=50, spinWaiting=50, fetchQueues.totalSize=814, fetchQueues.getQueueCount=1
    FetcherThread 48 fetching https://blog.csdn.net/h8y0bdjvukwe1lbozle/article/details/81117214 (queue crawl delay=5000ms)
    -activeThreads=50, spinWaiting=50, fetchQueues.totalSize=813, fetchQueues.getQueueCount=1
    -activeThreads=50, spinWaiting=50, fetchQueues.totalSize=813, fetchQueues.getQueueCount=1


查看数据库目录:

    [devalone@nutch nutch]$ ll testcrawl/
    总用量 0
    drwxrwxr-x 4 devalone devalone 32 7月  24 14:40 crawldb
    drwxrwxr-x 3 devalone devalone 21 7月  24 14:40 linkdb
    drwxrwxr-x 5 devalone devalone 72 7月  24 14:40 segments

数据库目录 testcrawl 被自动创建,并且在 testcrawl 内创建了 nutch 的三个数据库: crawldb,linkdb 和 segments。


观察后台执行的 nohup crawl 作业:
[devalone@nutch nutch]$ jobs
[1]+  运行中         nohup crawl -i -D solr.server.url=http://nutch.sansovo.org:8983/solr/crawl/ -s urls/ testcrawl 3 &

仍在运行中...

虽然脚本仍在运行,打开 solr 链接:http://nutch.sansovo.org:8983/solr/#/crawl/query

执行搜索任务,已经可以搜索到结果了,说明 crawl 脚本至少完成了一轮抓取过程。

...

运行完成时:
    [devalone@nutch nutch]$ jobs -l
    [1]+ 16512 完成  nohup crawl -i -D solr.server.url=http://nutch.sansovo.org:8983/solr/crawl/ -s urls/ testcrawl 3 &

    
    [devalone@nutch nutch]$ head nohup.out
    Injecting seed URLs
    /opt/nutch/nutch/bin/nutch inject testcrawl//crawldb urls/
    Injector: starting at 2018-07-24 14:35:11
    Injector: crawlDb: testcrawl/crawldb
    Injector: urlDir: urls


    [devalone@nutch nutch]$ tail nohup.out
    Indexer: number of documents indexed, deleted, or skipped:
    Indexer:   1057  indexed (add/update)
    Indexer: finished at 2018-07-24 16:15:54, elapsed: 00:00:08
    Cleaning up index if possible
    /opt/nutch/nutch/bin/nutch clean -Dsolr.server.url=http://nutch.sansovo.org:8983/solr/crawl/ testcrawl/crawldb
    SolrIndexer: deleting 3/3 documents
    2018年 07月 24日 星期二 16:15:57 CST : Finished loop with 3 iterations
    
    
对比启动和结束时间,共运行了 1:40:43。建立了 1057 个 URL 的 Solr 索引。并且最后一步执行了 Solr 清理。

打开 solr 链接:http://nutch.sansovo.org:8983/solr/#/crawl/query 执行搜索,获取更多的搜索结果。

 


6. 本地安装 Solr (Setup Solr for search)
-------------------------------------------------------------------------------------------------------------------------
每一个 Nutch版本对应一个特定的 Solr版本进行开发测试,但也可以尝试使用一个接近的版本。下面是 Nutch和 Solr版本的对应关系:

    +-------+-----------+
    | Nutch    | Solr        |
    +-------+-----------+
    | 1.14    | 6.6.0        |
    +-------+-----------+
    | 1.13    | 5.5.0        |
    +-------+-----------+
    | 1.12    | 5.4.1        |
    +-------+-----------+

 

6.1 本机模式安装 Solr
-------------------------------------------------------------------------------------------------------------------------
①  下载 Solr 二进制发布包
    
    访问站点 http://archive.apache.org/dist/lucene/solr/ 下载所需版本的二进制发布包,这里选择清华镜像站点 6.6.5 版本:

        [devalone@nutch solr]$ wget https://mirrors.tuna.tsinghua.edu.cn/apache/lucene/solr/6.6.5/solr-6.6.5.tgz

    
② 解压到合适的安装目录,本例为 /opt/solr/ 目录:
    
    [devalone@nutch solr]$ tar -zxvf solr-6.6.5.tgz
    [devalone@nutch solr]$ pwd
    /opt/solr
    [devalone@nutch solr]$ ll
    总用量 0
    drwxrwxr-x 9 devalone devalone 201 7月  23 16:30 solr-6.6.5
    
    [devalone@nutch solr]$ ll solr-6.6.5/
    总用量 1412
    drwxr-xr-x  3 devalone devalone    147 6月  30 13:28 bin
    -rw-r--r--  1 devalone devalone 693983 6月  30 13:28 CHANGES.txt
    drwxr-xr-x 12 devalone devalone    202 6月  30 14:22 contrib
    drwxrwxr-x  4 devalone devalone   4096 7月  23 16:30 dist
    drwxrwxr-x  3 devalone devalone     38 7月  23 16:30 docs
    drwxr-xr-x  7 devalone devalone    105 7月  23 16:30 example
    drwxr-xr-x  2 devalone devalone  24576 7月  23 16:30 licenses
    -rw-r--r--  1 devalone devalone  12646 2月  22 05:53 LICENSE.txt
    -rw-r--r--  1 devalone devalone 648213 6月  30 13:28 LUCENE_CHANGES.txt
    -rw-r--r--  1 devalone devalone  25549 5月  18 17:59 NOTICE.txt
    -rw-r--r--  1 devalone devalone   7271 5月  18 17:59 README.txt
    drwxr-xr-x 10 devalone devalone    157 7月  23 16:30 server

建立符号链接,方便使用:
    
    [devalone@nutch solr]$ sudo ln -s solr-6.6.5 solr
    [devalone@nutch solr]$ ll
    总用量 0
    lrwxrwxrwx 1 root     root      10 7月  23 16:34 solr -> solr-6.6.5
    drwxrwxr-x 9 devalone devalone 201 7月  23 16:30 solr-6.6.5
    
    [devalone@nutch solr]$ cd solr
    [devalone@nutch solr]$ pwd
    /opt/solr/solr
    
编辑 /etc/profile 文件,创建环境变量 SOLR_INSTALL, 并将 $SOLR_INSTALL/bin 加入 PATH 环境变量:

    [devalone@nutch solr]$ sudo vi /etc/profile

    SOLR_INSTALL=/opt/solr/solr
    PATH=$SOLR_INSTALL/bin:$PATH

    export PATH JAVA_HOME ANT_HOME NUTCH_INSTALL SOLR_INSTALL
    
    
    ● NOTE:
    ---------------------------------------------------------------------------------------------------------------------
    SOLR_HOME 环境变量已被 solr 占为他用,因此不要使用 SOLR_HOME 作为 solr 安装目录的环境变量,否则在启动 solr 时会出现
    如下错误:
    
        [devalone@nutch solr]$ bin/solr start
        
        Solr home directory /opt/solr-6.6.0 must contain a solr.xml file!
    
    本例使用 SOLR_INSTALL 作为 solr 安装目录的环境变量,运行没有问题。
    
    
保存退出,执行:
    
    [devalone@nutch solr]$ source /etc/profile
    
使其立即生效。

    [devalone@nutch solr]$ solr -version
    6.6.5
OK.


③ 为一个新 nutch solr core 创建资源:

    [devalone@nutch solr]$ cd server/solr/configsets/
    [devalone@nutch configsets]$ cp -r basic_configs nutch
    
④ 复制 nutch schema.xml 到 ${SOLR_INSTALL}/server/solr/configsets/nutch/conf 目录中

    [devalone@nutch solr]$ cp $NUTCH_INSTALL/conf/schema.xml $SOLR_INSTALL/server/solr/configsets/nutch/conf
    
    [devalone@nutch solr]$ ll $SOLR_INSTALL/server/solr/configsets/nutch/conf/
    总用量 168
    -rw-r--r-- 1 devalone devalone  3974 7月  23 16:49 currency.xml
    -rw-r--r-- 1 devalone devalone  1412 7月  23 16:49 elevate.xml
    drwxr-xr-x 2 devalone devalone  4096 7月  23 16:49 lang
    -rw-r--r-- 1 devalone devalone 58074 7月  23 16:49 managed-schema
    -rw-r--r-- 1 devalone devalone   308 7月  23 16:49 params.json
    -rw-r--r-- 1 devalone devalone   873 7月  23 16:49 protwords.txt
    -rw-rw-r-- 1 devalone devalone 22956 7月  23 16:55 schema.xml
    -rw-r--r-- 1 devalone devalone 55039 7月  23 16:49 solrconfig.xml
    -rw-r--r-- 1 devalone devalone   781 7月  23 16:49 stopwords.txt
    -rw-r--r-- 1 devalone devalone  1124 7月  23 16:49 synonyms.txt
    
⑤ 确保 $SOLR_INSTALL/server/solr/configsets/nutch/conf/ 目录内没有 managed-schema 文件:

    [devalone@nutch solr]$ rm $SOLR_INSTALL/server/solr/configsets/nutch/conf/managed-schema
    
⑥ 启动 solr 服务器:

    [devalone@nutch solr]$ solr start
    NOTE: Please install lsof as this script needs it to determine if Solr is listening on port 8983.

    Started Solr server on port 8983 (pid=5425). Happy searching!


⑦ 创建 nutch core :

    [devalone@nutch solr]$ bin/solr create -c nutch -d server/solr/configsets/nutch/conf/

    Copying configuration to new core instance directory:
    /opt/solr/solr/server/solr/nutch

    Creating new core 'nutch' using command:
    http://localhost:8983/solr/admin/cores?action=CREATE&name=nutch&instanceDir=nutch

    {
      "responseHeader":{
        "status":0,
        "QTime":1399},
      "core":"nutch"}

⑧ 将 core name 添加到 Solr server URL:

    -Dsolr.server.url=http://localhost:8983/solr/nutch
    
    或:
    -Dsolr.server.url=http://nutch.sansovo.org:8983/solr/nutch/
    
    ● NOTE:
    ---------------------------------------------------------------------------------------------------------------------
    这个字符串用于 nutch 命令中向 nutch 命令传递 solr 的服务器信息,例如 nutch index 命令,利用此字符串作为参数,为 solr
    中名称为 nutch 的 core 建立索引。有了索引之后,才能通过 http://localhost:8983/solr/nutch 进行搜索服务,如 4.5 节所述。
    
        
    
6.2 验证 Solr 安装
-------------------------------------------------------------------------------------------------------------------------
安装完成并启动 Solr 之后,应该可以通过如下链接访问 Solr:

    http://localhost:8983/solr/#/
    
    或:
    http://nutch.sansovo.org:8983/solr/#/


可以导航到 nutch core 并查看 managed-schema 等等。

 


-------------------------------------------------------------------------------------------------------------------------
参考:

    https://wiki.apache.org/nutch/NutchTutorial
   

你可能感兴趣的:(Nutch)