如何在python中为warc文件编写流式mapreduce作业

时间:2014-01-23 06:53:22

标签: python hadoop mapreduce hadoop-streaming warc

我正在尝试使用python的WARC library为warc文件编写mapreduce作业。 以下代码对我有用,但我需要这个代码用于hadoop mapreduce作业。

import warc
f = warc.open("test.warc.gz")
for record in f:
    print record['WARC-Target-URI'], record['Content-Length']

我希望此代码从warc文件读取流输入,即

zcat test.warc.gz | warc_reader.py

请告诉我如何为流式输入修改此代码。谢谢

1 个答案:

答案 0 :(得分:1)

warc.open()warc.WARCFile()的简写,并且warc.WARCFile()可以收到fileobj参数,其中sys.stdin正是文件对象。因此,您需要做的就是这样:

import sys
import warc

f = warc.open(fileobj=sys.stdin)
for record in f:
    print record['WARC-Target-URI'], record['Content-Length']

但是,当输入文件为.gz时,在hadoop流下会有些困难,因为hadoop会将WARC文件中的所有\r\n替换为\n,这将破坏WARC格式(请参阅此问题:hadoop converting \r\n to \n and breaking ARC format)。由于warc包使用正则表达式"WARC/(\d+.\d+)\r\n"来匹配标头(精确匹配\r\n),因此您可能会遇到以下错误:

IOError: Bad version line: 'WARC/1.0\n'

因此,您将按照所提到的问题中的建议修改PipeMapper.java文件,或编写自己的解析脚本,逐行解析WARC文件。

顺便说一句,简单地将warc.py修改为在匹配标头中使用\n而不是\r\n是不可行的,因为它读取的内容与Content-Length的长度完全相同,并期望之后有两个空行。因此hadoop所做的事情肯定会使内容的长度与属性Content-Length不匹配,从而导致另一个错误,例如:

IOError: Expected '\n', found 'abc\n'