我正在尝试使用 python 的 WARC 库为 warc 文件编写一个 mapreduce 作业。 以下代码对我有用,但我需要此代码用于 hadoopmapreduce 作业。
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
请告诉我如何修改此代码以进行流式输入。谢谢
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文件中的所有rn
替换为n
,这将破坏WARC格式(参考这个问题:hadoop将\r转换为并破坏ARC格式)。由于warc
包使用正则表达式"WARC/(d+.d+)rn"
来匹配标头(完全匹配rn
),因此您可能会收到此错误:
IOError: Bad version line: 'WARC/1.0n'
因此,您可以按照所提问题中的建议修改PipeMapper.java
文件,或者编写自己的解析脚本,该脚本逐行解析 WARC 文件。
顺便说一句,简单地修改warc.py
以在匹配的标头中使用n
而不是rn
是行不通的,因为它读取的内容与Content-Length
的长度完全相同,并且期望之后有两个空行。因此,hadoop 所做的肯定会使内容的长度与属性不匹配Content-Length
从而导致另一个错误,例如:
IOError: Expected 'n', found 'abcn'