我正在尝试使用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
请告诉我如何为流输入修改此代码。谢谢
发布于 2019-09-05 14:53:11
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'
https://stackoverflow.com/questions/21301337
复制相似问题