nutch[1] 是一个开源java实现的搜索引擎,它提供了我们运行自己的搜索引擎所需的全部工具,包括全文搜索和web爬虫。
solr[2]是一个基于lucene的全文搜索服务器,它对外提供类似于web-service的api查询接口,是一款非常优秀的全文搜索引擎。
为什么要整合nutch和solr?
简单地讲,nutch重在提供数据源采集(web爬虫)能力,轻全文搜索(lucene)能力;solr是lucene的扩展,亦是nutch的全文搜索的扩展。重在将nutch的爬取结果,通过其对外提供检索服务。
一、版本选择
1. nutch-1.13
支持hadoop,可以通过hadoop,获得分布式爬虫的能力。本文重点介绍nutch的原力,关于分布式爬虫,将在后续章节中介绍。另外,nutch-2.x系列支持hbase,可以根据自身的需要灵活选择。需要说明的是两版的用法是不同的,nutch-2.x要更为复杂。在使用nutch-2.x之前,最好具备nutch-1.x的基础。
2. solr-6.6.0
截止发稿时是最新版本,可参考ag真人试玩娱乐官网的解释,这里没什么要说的。
二、安装环境准备
1. 系统环境
ubuntu14.04x64 或 centos6.5x64, 应用程序采用二进制安装,不要求编译环境
2. java环境
vim /etc/profile
# set for java
export java_home=/opt/jdk1.8.0_111 #二进制包已经解压安装到该路径
export path=$path:$java_home/bin
export classpath=.:$classpath:$java_home/lib
export _java_options="xmx2048m xx:maxpermsize=512m djava.awt.headless=true"
注:java的安装方法选择二进制包即可,本文不再赘述
3. nutch solr环境
vim /etc/profile
export nutch_runtime_home='/opt/apache-nutch-1.13'
export path=$nutch_runtime_home/bin:$path
export apache_solr_home='/opt/solr-6.6.0' #单引号不能少
export path=$apache_solr_home/bin:$path
export classpath=.:$classpath:$apache_solr_home/server/lib
source /etc/profile #加载到环境
三、solr的安装与配置
solr的安装(二进制包)
wget http://mirror.bit.edu.cn/apache/lucene/solr/6.6.0/solr-6.6.0.tgz
cat solr-6.6.0.tgz |(cd /opt; tar xzfp -)
solr status #注:如果执行结果不正常,执行`source /etc/profile`和检查该文件的内容
no solr nodes are running.
#启动solr服务
solr start -force #-force:强制以root身份执行,生产环境请勿使用该参数
#停止solr服务
solr stop
安装完毕。
solr的配置
cd ${apache_solr_home}
cp -r server/solr/configsets/basic_configs server/solr/configsets/nutch
cp ${nutch_runtime_home}/conf/schema.xml server/solr/configsets/nutch/conf
mv server/solr/configsets/nutch/conf/managed-schema server/solr/configsets/nutch/conf/managed-schema.backup
#启动solr服务
solr start
#创建nutch core
solr create -c nutch -d server/solr/configsets/nutch/conf/ -force #-force:强制以root身份执行,生产环境请勿使用该参数
创建过程并非一帆风顺,整个过程充满了各种bug,从这个角度考虑,生产环境中有必要更换到solr的稳定版,好在这些坑已经趟过:
问题1:caused by: unknown parameters: {enablepositioninc rements=true}
具体信息:
copying configuration to new core instance directory:
/opt/solr-6.6.0/server/solr/nutch
creating new core 'nutch' using command:
http://localhost:8983/solr/admin/cores?action=create&name=nutch&instancedir=nutch
error: error createing solrcore 'nutch': unable to create core [nutch] caused by: unknown parameters: {enablepositionincrements=true}
解决办法:
vim server/solr/configsets/nutch/conf/schema.xml 找到并去掉enablepositionincrements=true
问题2:error: error createing solrcore 'nutch': unable to create core [nutch] caused by: defaultsearchfield has been deprecated and is incompatible with configs with lucenematchversion >= 6.6.0. use 'df' on requests instead.
解决办法:
vim server/solr/configsets/nutch/conf/solrconfig.xml 将lucenematchversion版本修改为6.2.0
问题3:org.apache.solr.common.solrexception: fieldtype 'booleans' not found in the schema
解决办法:
vim /opt/solr-6.6.0/server/solr/configsets/nutch/conf/solrconfig.xml
找到booleans,替换成boolean,如下:
java.lang.boolean
boolean
then it will work..
问题3以后,会发生多起类似事件,如下:
error: error createing solrcore 'nutch': unable to create core [nutch] caused by: fieldtype 'tdates' not found in the schema
error: error createing solrcore 'nutch': unable to create core [nutch] caused by: fieldtype 'tlongs' not found in the schema
error: error createing solrcore 'nutch': unable to create core [nutch] caused by: fieldtype 'tdoubles' not f ound in the schema
参照问题3的方法,一次性去掉''中关键字的复数形式即可。
问题4:error:
core 'nutch' already exists!
checked core existence using core api command:
http://localhost:8983/solr/admin/cores?action=status&core=nutch
解决办法:
solr delete -c nutch #删除core 'nutch'
如果删除完,还提示这个错误,这是由于每次修改完配置文件,需要重启下solr服务,更新下状态。
最终的执行结果:
solr create -c nutch -d server/solr/configsets/nutch/conf/ -force
copying configuration to new core instance directory:
/opt/solr-6.6.0/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":3408},
"core":"nutch"}
执行成功!
在浏览器中访问
http://localhost:8983/solr/#/
可以看到名称为nutch的core
solr的安全设置
1. realm.properties
cd /opt/solr-6.6.0/server
cat etc/realm.properties
#
# 这个文件定义用户名,密码和角色
#
# 格式如下
# : [, ...]
#
#username: password,role
yourname: yourpass,admin
2. solr-jetty-context.xml
cat contexts/solr-jetty-context.xml
/solr-webapp/webapp
/etc/webdefault.xml
false
solr admin access
/etc/realm.properties
3. web-inf/web.xml
vim solr-webapp/webapp/web-inf/web.xml
...
solr auth enticated application
/
admin
basic
solr admin access
重启solr服务
solr stop && solr start -force
在浏览器中访问solr
http://localhost:8983/solr/nutch/
可以看到要求登录的界面
四、nutch的安装与配置
nutch的安装(二进制包)
wget http://mirrors.hust.edu.cn/apache/nutch/1.13/apache-nutch-1.13-bin.tar.gz
cat apache-nutch-1.13-bin.tar.gz |(cd /opt; tar xzfp -)
nutch -help #注:如果执行结果不正常,执行`source /etc/profile`和检查该文件的内容
安装完毕。
nutch的配置
以爬取http://nutch.apache.org站点为例,配置如下:
1. 配置nutch-site.xml
vim $nutch_runtime_home/conf/nutch-site.xml
http.agent.name
my nutch spider
#配置indexer-solr插件
#我的方法是替换indexer-elastic为indexer-solr插件
sed -i 's/indexer-elastic/indexer-solr/g' $nutch_runtime_home/conf/nutch-site.xml
#注意:官方文档不是像我这样做的,请按照我的方法配置,或者注释掉indexer-elastic,否则会深受其害,踩坑过程后面会说
2. 建立url列表
#为方便修改配置文件,选择conf文件夹作为数据的存储路径
cd $nutch_runtime_home/conf
mkdir -p urls #存储要爬取的urls列表,每行只写一个url,可以多行
cd urls
echo 'http://nutch.apache.org/' > seed.txt #地址可以是静态的链接,也可以是动态的链接
3. 设置url的正则匹配规则
vim regex-urlfilter.txt
将光标移到文件末尾,将下列内容:
# accept anything else
.
替换为:
# accept anything else
^http://([a-z0-9]*\.)*nutch.apache.org/ #这将包含带有域名前缀的url,比如,http://3w.nutch.apache.org
4. 允许抓取动态内容
vim crawl-urlfilter.txt regex-urlfilter.txt
替换:
# skip urls containing certain characters as probable queries, etc.
-[?*!@=]
为:
# accept urls containing certain characters as probable queries, etc.
[?=&]
注: conf下有各种配置文件,涉及各种爬取规则和正则过滤器。将在后续的文章中详细说明
五、爬取和检索的过程
1. nutch爬取程序的概念组成
抓取程序自动在用户指定目录下面建立爬取目录,其目录下可以看到crawldb,segments,linkdb子目录
1. crawldb(爬虫数据库)
crawldb目录下面存放下载的url,以及下载的日期、过期时间
2. linkdb-链接数据库
linkdb目录存放url的关联关系,是下载完成后分析时创建的,通过这个关联关系可以实现类似google的pagerank功能
3. segments-一组分片
segments目录存储抓取的页面,这些页面是根据层级关系分片的。既segments下面子目录的个数与获取页面的层数有关系,如果指定“-depth”参数是10层,这个目录下就有10层,结构清晰并防止文件过大。
segments目录里面有6个子目录,分别是:
“crawl_generate” 生成要获取的一组url的名字,既生成待下载的url的集合
“crawl_fetch” 包含获取每个ur l的状态
”content“ 包含从每个url检索的原始内容
“parse_text” 包含每个url的解析文本(存放每个解析过的url的文本内容)
“parse_data” 包含从每个url分析的外部链接和元数据
“crawl_parse” 包含用于更新crawldb的outlink url(外部链接库)
2. nutch的爬取流程说明
爬取过程包括
injector -> generator -> fetcher -> parsesegment -> updatecrawledb -> invert links -> index -> deleteduplicates -> indexmerger
1. 根据之前建好的url列表文件,将url集注入crawldb数据库---inject
2. 根据crawldb数据库创建抓取列表---generate
3. 执行抓取,获取网页信息---fetch
4. 执行解析,解析网页信息---parse
5. 更新数据库,把获取到的页面信息存入数据库中---updatedb
6. 重复进行2~4的步骤,直到预先设定的抓取深度。---这个循环过程被称为“产生/抓取/更新”循环
7. 根据sengments的内容更新linkdb数据库---invertlinks
8. 建立索引---index
3. solr查询流程包括
- 用户通过用户接口进行查询操作
- 将用户查询转化为solr查询
- 从索引库中提取满足用户检索需求的结果集
六、爬取和检索的实例
1. inject
nutch inject crawl/crawldb urls
2. generate
nutch generate crawl/crawldb crawl/segments
3. fetching
s1=`ls -d crawl/segments/2* | tail -1`
echo $s1
nutch fetch $s1
4. parse
nutch parse $s1
5. updatedb
nutch updatedb crawl/crawldb $s1
6. 循环抓取
重复2-4的过程,抓取下一层页面
演示过程中,为了节约时间,我们约定一个参数,只抓取前 top 1000 的页面
nutch generate crawl/crawldb crawl/segments -topn 1000
s2=`ls -d crawl/segments/2* | tail -1`
echo $s2
nutch fetch $s2
nutch parse $s2
updatedb:nutch updatedb crawl/crawldb $s2
重复2-4的过程,抓取下下层的页面
同样只取前1000个页面进行抓取
nutch generate crawl/crawldb crawl/segments -topn 1000
s3=`ls -d crawl/segments/2* | tail -1`
echo $s3
nutch fetch $s3
nutch parse $s3
updatedb:nutch updatedb crawl/crawldb $s3
这样我们总共抓取了三个层级深度的页面
ls crawl/segments/
20170816191100 20170816191415 20170816192100
7. invertlinks
nutch invertlinks crawl/linkdb -dir crawl/segments
8. indexing into apache solr(推送solr index)
nutch index -dsolr.server.url=http://用户名:密码@localhost:8983/solr/nutch crawl/crawldb/ -linkdb crawl/linkdb/ crawl/segments/20170816191100/ -filter -normalize -deletegone
#这里的“用户名:密码”是solr的jetty下的
值得一提的是,如果按照官方标准语法,上面命令会变为:
nutch index -dsolr.auth.username="yourname" -dsolr.auth.password="yourpassword" -dsolr.server.url=http://localhost:8983/solr/nutch crawl/crawldb/ -linkdb crawl/linkdb/ crawl/segments/20170816191100/ -filter -normalize -deletegone
这里会提示语法错误,在ag真人试玩娱乐官网和google上还没有更好的解决办法。我已经把上面的方法更新到
http://lucene.472066.n3.nabble.com/nutch-authentication-problem-to-solr-td4251336.html#a4351038
可能其它版本没有这个问题。
最终的推送结果如下:
nutch index -dsolr.server.url=http://xxx:xxx@localhost:8983/solr/nutch crawl/crawldb/ -linkdb crawl/linkdb/ crawl/segments/20170816191100/ -filter -normalize -deletegone
segment dir is co mplete: crawl/segments/20170816191100.
indexer: starting at 2017-08-17 18:22:26
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 1/1 documents
deleting 0 documents
indexer: number of documents indexed, deleted, or skipped:
indexer: 1 indexed (add/update)
indexer: finished at 2017-08-17 18:22:32, elapsed: 00:00:05
9. 在solr上查询
在浏览器中访问solr
http://localhost:8983/solr/
10. 通过脚本自动完成1-9
crawl -i -d solr.server.url=http://用户名:密码@localhost:8983/solr/ urls/ crawl/ 2