NUTCH中的not in gzip format异常处理

Nutch爬虫爬取某网页是出现下列异常:

ERROR http.Http (?:invoke0(?)) - java.io.IOException: unzipBestEffort returned null

ERRORhttp.Http(?:invoke0(?))-atorg.apache.nutch.protocol.http.api.HttpBase.processGzipEncoded(HttpBase.java:472)

ERRORhttp.Http(?:invoke0(?))-atorg.apache.nutch.protocol.http.HttpResponse.<init>(HttpResponse.java:151)

ERRORhttp.Http(?:invoke0(?))-atorg.apache.nutch.protocol.http.Http.getResponse(Http.java:63)

ERRORhttp.Http(?:invoke0(?))-atorg.apache.nutch.protocol.http.api.HttpBase.getProtocolOutput(HttpBase.java:208)

ERROR http.Http (?:invoke0(?)) - at org.apache.nutch.fetcher.Fetcher$FetcherThread.run(Fetcher.java:173)

经过调试发现异常来源于:

java.io.IOException: Not in GZIP format

atjava.util.zip.GZIPInputStream.readHeader(GZIPInputStream.java:137)

atjava.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:58)

atjava.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:68)

该异常原因:

此页面采用这个是一个分段传输,而nutch爬虫则默认采用了非分段式处理,导致构造GZIP时出错,从而影响了后面的GZIP解压失败。

是否是分段传输可以在Http headers里面看到,如果是分段传输则有:transfer-encoding:chunked这样一个响应。

处理方法:

1. 修改接口org.apache.nutch.metadata.HttpHeaders, 添加:

public final static String TRANSFER_ENCODING = "Transfer-Encoding";

2. 在nutch中的org.apache.nutch.protocol.http.HttpResponse类中已经提供了分段传输类型的处理方法:

private void readChunkedContent(PushbackInputStream in,  
                                  StringBuffer line)

我们只需要在HttpResponse的构造方法总调用该方法即可,添加如下代码:

String transferEncoding = getHeader(Response.TRANSFER_ENCODING);
      
      if(transferEncoding != null && transferEncoding.equalsIgnoreCase("chunked")){
         StringBuffer line = new StringBuffer();
       this.readChunkedContent(in, line);
        }else{
         readPlainContent(in);
        }

修改完成,运行测试。

NUTCH中的not in gzip format异常处理NUTCH中的not in gzip format异常处理刚才不能爬取的站点终于可以爬取了

相关推荐