我正在尝试使用 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/

10-13 09:01