WARC里的HTTP响应

WARC是一种格式。Heritrix([url]http://crawler.archive.org/[/url])用它原封不动地储存HTTP请求和HTTP响应的全文。包括请求/状态行、头、内容。

读WARC格式很简单。利用Heritrix中提供的工具即可。


package warc;

import java.io.*;

import org.apache.commons.io.IOUtils;
import org.archive.io.*;
import org.archive.io.warc.*;

public class MyWarcReading {

public static void main(String[] args) throws Exception {
ArchiveReader ar = WARCReaderFactory.get("/path/to/your/file.warc.gz");

// ArchiveReader对象本身实现了Iterator<ArchiveRecord>接口,可以用for循环。
for (ArchiveRecord rec : ar) {
// 获取WARC记录头。
ArchiveRecordHeader header = rec.getHeader();

// 可以对header做一些操作。

// 读出这条记录的内容。ArchiveRecord继承了InputStream类。
// 我使用了Commons-IO。不过这样读太暴力了……
byte[] content = IOUtils.toByteArray(rec);

// 对内容做什么都行。
}

ar.close();
}

}


如果里面储存了爬虫爬的结果,那么整个HTTP响应会成为一条记录的内容。这种记录是原封不动的响应,包括status line, headers, entity,都有。mimetype是application/http,如HTTP/1.1的RFC中所述。


ArchiveRecord rec; // 一条记录
if(rec.getHeader().getMimetype().equals(
"application/http; msgtype=response")) {
// 这是HTTP响应
}


如何解析这个响应呢?

想过用Apache Httpcomponents([url]http://hc.apache.org/[/url])的HTTP Core,但是它的解析器与Socket耦合太强,还使用了很多自己的数据结构以提高效率。Jetty的解析器没有文档(undocumented)。

最后,发现如果只是想读HTTP头,还是用BufferedReader自己读比较好。


private static void parseHtml(ArchiveRecord rec) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(rec,"ISO-8859-1"));
String statusLine = br.readLine();
System.out.println("Status:"+statusLine);

System.out.println("===HTTP headers===");
while(true) {
String line = br.readLine();
if(line==null || line.isEmpty()) {
break;
}
System.out.println(line);
}

byte[] bytes = IOUtils.toByteArray(rec); // WRONG!
System.out.println("===HTTP entity===");
System.out.println(new String(bytes, "UTF-8"));
}


但是,由于BufferedReader的缓冲,此时读出的entity是不正确的。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值