pstatus = output(fit.url, fit.datum, content,
status,
CrawlDatum.STATUS_FETCH_SUCCESS,
fit.outlinkDepth);
--------------------------------------------代码如下:
datum.setStatus(status);//保存爬取状态
datum.setFetchTime(System.currentTimeMillis());//保存抓取时间
---------------保存psk
if (pstatus != null)
datum.getMetaData().put(Nutch.WRITABLE_PROTO_STATUS_KEY,
pstatus);
-------------
ParseResult parseResult = null;
if (content != null)
{
Metadata metadata = content.getMetadata();
// store the guessed content type in the crawldatum
if (content.getContentType() != null)
datum.getMetaData().put(new Text(Metadata.CONTENT_TYPE),
new Text(content.getContentType()));//保存内容类型
// add segment to metadata
metadata.set(Nutch.SEGMENT_NAME_KEY, segmentName);//在content中保存segmentName.
-------------- 接下来
// add score to content metadata so that ParseSegment can pick
// it up.
try {
scfilters.passScoreBeforeParsing(key, datum, content);
} catch (Exception e) {
if (LOG.isWarnEnabled()) {
LOG.warn("Couldn't pass score, url " + key + " (" + e
+ ")");
}
}
根据打印信息,这里的scfilters只有1个,就是:
org.apache.nutch.scoring.opic.OPICScoringFilter
它的相应代码为:
/** Store a float value of CrawlDatum.getScore() under Fetcher.SCORE_KEY. */
public void passScoreBeforeParsing(Text url, CrawlDatum datum, Content content) {
content.getMetadata().set(Nutch.SCORE_KEY, "" + datum.getScore());
}
也就是把datum中的分数转移到了content中。
------------------------------------------------------------------------------------------------
if (parsing && status == CrawlDatum.STATUS_FETCH_SUCCESS) {
if (!skipTruncated
|| (skipTruncated && !ParseSegment
.isTruncated(content))) {
try {
parseResult = this.parseUtil.parse(content);
} catch (Exception e) {
LOG.warn("Error parsing: " + key + ": "
+ StringUtils.stringifyException(e));
}
}
if (parseResult == null) {
byte[] signature = SignatureFactory.getSignature(
getConf()).calculate(content,
new ParseStatus().getEmptyParse(conf));
datum.setSignature(signature);
}
}
不过这里的parsing------------false
所以,暂时不用考虑上面这段代码,等后续进入parsing环节再考虑。
------------
output.collect(key, new NutchWritable(datum));
if (content != null && storingContent)
output.collect(key, new NutchWritable(content));
总的来说,上面是对fetch的依据datum和fetch的结果content进行设置。
所以这里要写入到文件中了,这3行代码就是起这个作用。
----------------------------------------------------------
好,由于这里不进行解析,所以parseResult为null,后面的代码也不用执行了。
接下来是:
updateStatus(content.getContent().length);
具体代码为:
private void updateStatus(int bytesInPage) throws IOException {
pages.incrementAndGet();
bytes.addAndGet(bytesInPage);
}
这里是做一个信息统计,没啥好说的。
然后由于[FetcherThread]---------------------------pstatus:null
所以后面一大段代码不执行。
-------------------------------------------------------------------------
直接执行break;
if (redirecting && redirectCount > maxRedirect) {
fetchQueues.finishFetchItem(fit);
if (LOG.isInfoEnabled()) {
LOG.info(" - redirect count exceeded "
+ fit.url);
}
output(fit.url, fit.datum, null,
ProtocolStatus.STATUS_REDIR_EXCEEDED,
CrawlDatum.STATUS_FETCH_GONE);
}
} while (redirecting && (redirectCount <= maxRedirect));
这里是关于重定向的代码逻辑,按下不表!
-------------------------------------------最后是退出线程的代码逻辑
finally {
if (fit != null)
fetchQueues.finishFetchItem(fit);//去掉当前item.
activeThreads.decrementAndGet(); // count threads//活跃线程减少
LOG.info("-finishing thread " + getName() + ", activeThreads="
+ activeThreads);
}
至此,FetcherThread全部分析完了。