Nutch 是一个开源Java 实现的爬虫框架和搜索引擎。支持分布式处理,有两个主版本1.x和2.x,它们的主要区别是1.x版本底层存储使用的是HDFS,2.x引入了Gora作为存储抽象层,从而支持各种NoSQL数据库,如HBase,Cassandra等,另外也支持mysql
具体的安装步骤可以参考http://blog.csdn.net/lzjzy520/article/details/41596893,这里仅补充自身遇到的几个问题.
一.2.3.1版本ant编译时候, 会卡在 loading settings :: file = /usr/java/apache-nutch-2.3.1/ivy/ivysettings.xml,等待很久没反应, 因此选择了安装2.2.1版本
二.ant编译过程较久,我第一次编译成功花了40多分钟,所以得耐心等待
三.我是在不修改maven仓库地址的情况下编译成功,仓库地址修改为http://mirrors.ibiblio.org/maven2/或者http://maven.oschina.net/content/groups/public/时编译失败,如果jar包下载不了,可以试试来回切换仓库地址或者使用阿里云的maven仓库地址
四.在linux环境下安装,nutch版本使用2.2.1,solr版本使用4.4.0,hbase版本使用0.90.4
首先,将nutch源码导入到eclipse. nutch安装目录下列称为NUTCH_HOME,另外,以尽量少改动源码和写自定义插件的前提下开发
NUTCH_HOME/runtime/local/conf/nutch-site.xml文件,添加
plugin.includes
protocol-http|protocol-httpclient|urlfilter-regex|parse-(html|tika|metatags)|filter-xpath|index-(basic|metadata|anchor|more)|scoring-opic|urlnormalizer-(pass|regex|basic)|language-identifier
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.
可以将cookie信息也放在这个文件中,如添加
cookie.value
BAIDUID=24B253A73C44B95F9D0A876F23FCAAAA:FG=1;BDSVRTM=0
接下来,修改源码src/plugin/protocol-httpclient/src/java/Http.java,
在setConf()方法添加cookieValue变量读取cookie值,在configureClient()方法给header添加Cookie
public void setConf(Configuration conf) {
//其他代码略.....
cookieValue = conf.get("cookie.value", "");
//其他代码略....
}
private void configureClient() {
//....
headers.add(new Header("Cookie", cookieValue));
//....
}
nutch会收集当前页面的url,那么如何将我们自己要想的url添加进去呢?
首先解析要抓取页面,一共有多少分页.可以找到这个类src/plugin/parse-html/src/java/HtmlParser.java
getParse(String url, WebPage page)方法中,
utils.getText(sb, root); // extract text
text = sb.toString(); //这里的text就是页面的文本内容
我们可以看到在DOMContentUtils.getTextHelper()方法遍历了dom节点,通过使用DOM方法获取到总页数,然后可以组装好
url,在NUTCH_HOME/runtime/local/urls/目录下生产存放url地址的文件. 就是说,让nutch在下一次抓取时候,去访问你这次的url.
另外,也可以在HtmlParser.java的sniffCharacterEncoding(ByteBuffer content) 方法,str变量是整个页面的html代码,可以用 jsoup进行解析.
如果不想将url保存到文件中,还有一个思路就是将url更新到crawldb中,看下HtmlParser类中如下的2行代码
utils.getOutlinks(baseTag!=null?baseTag:base, l, root);
outlinks = l.toArray(new Outlink[l.size()]);
我们可以添加自己的url到outlinks集合中.
默认情况下,nutch会保存抓取页面中的一些HTML标签href属性的url,下次执行命令时候就会抓取这些链接地址.有时候我们并不需要这些额外的数据.这种情况下HtmlParser类的outlinks变量就不需要处理了.
保存outlinks的代码在src/java/crawl/DbUpdateMapper的map方法
Map outlinks = page.getOutlinks();
if (outlinks != null) {
for (Entry e : outlinks.entrySet()) {
int depth=Integer.MAX_VALUE;
Utf8 depthUtf8=page.getFromMarkers(DbUpdaterJob.DISTANCE);
if (depthUtf8 != null) depth=Integer.parseInt(depthUtf8.toString());
scoreData.add(new ScoreDatum(0.0f, e.getKey().toString(),
e.getValue().toString(), depth));
}
}
运行Crawler的main方法时候会报错. GeneratorReducer第100行, 代码如下:
batchId = newUtf8(conf.get(GeneratorJob.BATCH_ID));
这里的conf.get(GeneratorJob.BATCH_ID)为空报错.
解决方法,修改GeneratorJob中的public Map
// generate batchId
int randomSeed = Math.abs(new Random().nextInt());
String batchId = (curTime / 1000) + "-" + randomSeed;
getConf().set(BATCH_ID, batchId);
同样的,SolrIndexerJob的第40行,String batchId = (String)args.get(Nutch.ARG_BATCH);因为也为空值而报错,这里
可以给batchId指定一个值.能达到运行源码正常就行,这时就可以DEBUG详细的查看nutch如何运行了.
Nutch属于Apache的, 支持分布式处理,包含web爬虫和全文搜索功能,看起来美美的.
不过,用起来蛮复杂的,二次开发不够灵活也略显麻烦,抓取目标不特定,后期有变动的话,要修改的地方会很多.
如果nutch能满足你80%的需求,如果不考虑后期需求变动会有比较大的修改,看了源码后如果觉得自己可以hold住它,可以使用.
否则个人建议还是自己开发会简单些.