我正在尝试使用 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
请告诉我如何修改此代码以进行流式输入。谢谢
最佳答案
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"
来匹配 header (完全匹配 \r\n
),您可能会收到此错误:IOError: Bad version line: 'WARC/1.0\n'
因此,您将按照引用问题中的建议修改
PipeMapper.java
文件,或者编写自己的解析脚本,该脚本逐行解析 WARC 文件。顺便说一句,简单地修改
warc.py
以在匹配的 header 中使用 \n
而不是 \r\n
是行不通的,因为它读取的内容与 Content-Length
的长度完全相同,并且在此之后需要两个空行。因此,hadoop 所做的肯定会使内容的长度与属性 Content-Length
不匹配,从而导致另一个错误,例如:IOError: Expected '\n', found 'abc\n'
关于python - 如何在python中为warc文件编写流式mapreduce作业,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21301337/