我正在尝试使用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
请告诉我如何为流式输入修改此代码。谢谢
答案 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'