Nutch2.3 安装与部署
Nutch是由JAVA开发的开源的全文检索引擎.不过更多的被用来当成Web爬虫来使用.现在Nutch分为了1.x和2.x两个版本在维护.而这两个版本的最主要的区别在于底层存储的抽象.1.x版本是基于Hadoop架构的,底层存储只能使用HDFS.而2.x版本通过Apache Gora对底层存储做了抽象,能访问HBase,MYSQL,MongoDB,Solr,AvroStore等等.
但是从2.X开始,官方就只提供源码的下载了,不再提供编译后的发布版本,因此就需要我们自己去进行编译.
编译
为了简便起见,我们准备底层的存储使用mongoDB. 因此,这个演示是基于 Nutch+MongoDB的.
下载源码
从官网上下载http://www.apache.org/dyn/closer.lua/nutch/2.3/apache-nutch-2.3-src.tar.gz.然后执行命令tar -xvf apache-nutch-2.3-src.tar.gz
进行解压.修改
$NUTCH_HOME/conf/nutch-site.xml
,增加以下内容:123456789101112<configuration><property><name>storage.data.store.class</name><value>org.apache.gora.mongodb.store.MongoStore</value><description>Default class for storing data</description></property><property><name>http.agent.name</name><value>My Nutch Spider</value></property></configuration>```修改
$NUTCH_HOME/conf/gora.properties
,在最下面找到# MongoDBStore properties #
,然后打开注释:12345678910############################# MongoDBStore properties #############################gora.datastore.default=org.apache.gora.mongodb.store.MongoStoregora.mongodb.override_hadoop_configuration=falsegora.mongodb.mapping.file=/gora-mongodb-mapping.xmlgora.mongodb.servers=localhost:27017gora.mongodb.db=mytestdatabase#gora.mongodb.login=login#gora.mongodb.secret=secret注意,如果你的mongo数据库没有auth,最后两行需要注释掉.
修改
$NUTCH_HOME/ivy/ivy.xml
.去掉下面的注释,使用gora-hbase:12<!-- Uncomment this to use MongoDB as Gora backend. --><dependency org="org.apache.gora" name="gora-mongodb" rev="0.5" conf="*->default" />这个地方需要特别注意一下,这里虽然使用了
gora-mongodb-0.5
,但是这个版本其实是有问题的,会在后面抓取记录保存到MongoDB的时候报:java.lang.IllegalArgumentException: can't serialize class org.apache.avro.util.Utf8
的异常,开始折腾了我很久.最后发现了这个是gora-mongodb-0.5
自身的一个Bug,在0.6中是被修复了的.因此,我最开始想把整个gora升级成为0.6,结果Nutch不能执行.因此,目前阶段如果你底层想要使用MongoDB进行存储的话,需要单个把gora-mongodb
升级到0.6
版本,而其他的不动.接下来就是编译了,直接在
$NUTCH_HOME
根目录上执行ant runtime
即可.
但是这个速度不得不吐槽.非常的坑爹,基本上下了我3个多小时.不知道是什么原因,我平时使用JAVA的Maven环境的时候下载其实是非常的快的.但是IVY的依赖下载就非常非常非常的慢.理论上他们是同一个网络地址啊. 为了能加速那么一丢丢.可以把$NUTCH_HOME/ivy/ivysettings.xml
中的repo.maven.org
给替换成国内的镜像.比如:123<property name="repo.maven.org"value="http://maven.oschina.net/content/groups/public/"override="false"/>其他的两个不能替换,我换了以后会找不到包的.
如果你的编译长时间的停在
[ivy:resolve] :: loading settings :: file = $NUTCH_HOME/ivy/ivysettings.xml
.那么你可以把进程杀了重新执行一次ant runtime
.可能执行个十来次就能编译成功了.最终,会显示:
123456job:[jar] Building jar: $NUTCH_HOME/build/apache-nutch-2.3.jobruntime:[copy] Copying 1 file to $NUTCH_HOME/nutch/runtime/deploy[copy] Copying 2 files to $NUTCH_HOME/nutch/runtime/local/libBUILD SUCCESSFUL然后会在你的
$NUTCH_HOME
目录下,创建runtime
和build
目录. 其中的runtime
目录即为你编译好了的Nutch2.3
.如果在编译过程中出现
Could not load definitions from resource org/sonar/ant/antlib.xml.It could not be found.
的警告的话,不要着急,这个错误不影响你最后的编译是否成功.如果你有强迫症,见不得有警告的话.那么可以到Maven中下载sonar-ant-task-2.2.jar
包,然后放入$NUTCH_HOME/lib
,然后修改$NTUCH_HOME/build.xml
即可:123456<!-- Define the Sonar task if this hasn't been done in a common script --><taskdef uri="antlib:org.sonar.ant" resource="org/sonar/ant/antlib.xml"><classpath path="${ant.library.dir}" /><classpath path="${mysql.library.dir}" /><classpath><fileset dir="lib/" includes="sonar*.jar" /></classpath></taskdef>
部署
其实编译完成后的runtime
文件夹就已经是一个完整的可以运行的环境了.
我们在这里做一个简单的测试:使用Nutch爬取cnbeta中的新闻文章.
在
$NUTCH_HOME/runtime/local
下创建一个文件seed.txt
. 里面就是需要爬取的网站,一行一个.我们在这里只写一行:www.cnbeta.com
修改
$NUTCH_HOME/runtime/cong/automaton-urlfilter.txt
文件,这个文件就是URL的过滤.避免爬取到不需要的网站.12345# accept anything else+^http://www.cnbeta.com/$+^http://www.cnbeta.com/articles/\d\.htm$# skip everything else-.然后在命令行中执行
$NUTCH_HOME/runtime/bin/crawl seed.txt test 2
.
这个时候就会开始爬取目标网站了.你会看到很多的日志信息:123456789101112131415fetching http://www.cnbeta.com/topics/8.htm (queue crawl delay=5000ms)50/50 spinwaiting/active, 71 pages, 10 errors, 0.2 0 pages/s, 67 102 kb/s, 28 URLs in 1 queuesfetching http://www.cnbeta.com/topics/464.htm (queue crawl delay=5000ms)50/50 spinwaiting/active, 72 pages, 10 errors, 0.2 0 pages/s, 67 102 kb/s, 27 URLs in 1 queuesfetching http://www.cnbeta.com/topics/455.htm (queue crawl delay=5000ms)50/50 spinwaiting/active, 73 pages, 10 errors, 0.2 0 pages/s, 68 102 kb/s, 26 URLs in 1 queuesfetching http://www.cnbeta.com/topics/83.htm (queue crawl delay=5000ms)49/50 spinwaiting/active, 73 pages, 10 errors, 0.2 0 pages/s, 67 0 kb/s, 25 URLs in 1 queues50/50 spinwaiting/active, 74 pages, 10 errors, 0.2 0 pages/s, 67 102 kb/s, 25 URLs in 1 queuesfetching http://www.cnbeta.com/topics/444.htm (queue crawl delay=5000ms)50/50 spinwaiting/active, 75 pages, 10 errors, 0.2 0 pages/s, 68 102 kb/s, 24 URLs in 1 queuesfetching http://www.cnbeta.com/commentrss.php (queue crawl delay=5000ms)50/50 spinwaiting/active, 76 pages, 10 errors, 0.2 0 pages/s, 67 0 kb/s, 23 URLs in 1 queuesfetching http://www.cnbeta.com/topics/197.htm (queue crawl delay=5000ms)50/50 spinwaiting/active, 77 pages, 10 errors, 0.2 0 pages/s, 67 102 kb/s, 22 URLs in 1 queues等一段时间后,爬取就完成了.然后打开Mongo数据库,就会看到有一个
mytestdatabase
的库.里面有一个test_webpage
的表,其中的东西就是爬虫爬取的内容了.随便抓取一个举例:123456789101112131415161718192021222324252627282930313233343536373839404142{"_id": "com.cnbeta.www:http/articles/447355.htm","status": 2,"fetchTime": NumberLong(1449587050404),"fetchInterval": 2592000,"retriesSinceFetch": 0,"score": 0.0,"inlinks": {"http://www·cnbeta·com/": ""},"markers": {"_gnmrk_": "1449586889-28161","_ftcmrk_": "1449586889-28161","dist": "1"},"metadata": {"_rs_": BinData(0, "AAABzw==")},"batchId": "1449586889-28161","baseUrl": "http://www.cnbeta.com/articles/447355.htm","prevFetchTime": NumberLong(1449586888595),"protocolStatus": {"code": 1,"args": [],"lastModified": NumberLong(0)},"content": BinData(0, "XXXXXX网页的内容,太长了,就省略了"),"contentType": "application/xhtml+xml","headers": {"Vary": "Accept-Encoding","Date": "Tue, 08 Dec 2015 15:04:10 GMT","Last-Modified": "Sun, 06 Dec 2015 02:11:14 GMT","Content-Encoding": "gzip","Content-Type": "text/html","Accept-Ranges": "bytes","Connection": "close","Server": "grid-cache/1.4.4","X-CDNZZ-FCACHE": "EXPIRED"}}这就是爬取下来的内容.就可以通过我们进一步处理了.
而这个字段的定义是在$NUTCH_HOME/runtime/local/conf/gora-mongodb-mapping.xml
中定义的.
结束语
这样,一个最简单的Nutch的运行环境就搭建成功了.更多的更高级的功能,我们后面再慢慢来试验.