2015-05-20 3 views
0

Я пытаюсь проанализировать файлы .warc с Common Crawl в Python.Как читать подмножество записей из файла warc

Поскольку файлы огромны, я хочу начать с образца/подмножества первых нескольких записей.

Как усечь файл, чтобы он включал только первые строки X, сохраняя при этом возвращаемые символы новой строки/каретки?

Вот что я уже пробовал:

  1. head -n 250 oldfile > newfile Это устраняет некоторые из возвращений, которые необходимы для разбора файла. Вот ошибка я получаю, если я пытаюсь использовать этот файл в моей Hadoop работе (чтение его с warc пакета):

    Traceback (most recent call last): 
         File "test.py", line 46, in <module> 
         TagGrabber.run() 
         File "/var/cc-mrjob/venv/local/lib/python2.7/site-packages/mrjob/job.py", line 461, in run 
         mr_job.execute() 
         File "/var/cc-mrjob/venv/local/lib/python2.7/site-packages/mrjob/job.py", line 479, in execute 
         super(MRJob, self).execute() 
         File "/var/cc-mrjob/venv/local/lib/python2.7/site-packages/mrjob/launch.py", line 151, in execute 
         self.run_job() 
         File "/var/cc-mrjob/venv/local/lib/python2.7/site-packages/mrjob/launch.py", line 214, in run_job 
         runner.run() 
         File "/var/cc-mrjob/venv/local/lib/python2.7/site-packages/mrjob/runner.py", line 464, in run 
         self._run() 
         File "/var/cc-mrjob/venv/local/lib/python2.7/site-packages/mrjob/sim.py", line 173, in _run 
         self._invoke_step(step_num, 'mapper') 
         File "/var/cc-mrjob/venv/local/lib/python2.7/site-packages/mrjob/sim.py", line 264, in _invoke_step 
         self.per_step_runner_finish(step_num) 
         File "/var/cc-mrjob/venv/local/lib/python2.7/site-packages/mrjob/local.py", line 152, in per_step_runner_finish 
         self._wait_for_process(proc_dict, step_num) 
         File "/var/cc-mrjob/venv/local/lib/python2.7/site-packages/mrjob/local.py", line 268, in _wait_for_process 
         (proc_dict['args'], returncode, ''.join(tb_lines))) 
        Exception: Command ['sh', '-ex', 'setup-wrapper.sh', '/var/cc-mrjob/venv/bin/python', 'test.py', '--step-num=0', '--mapper', '/tmp/test.root.20150520.071726.549519/input_part-00000'] returned non-zero exit status 1: 
        Traceback (most recent call last): 
         File "test.py", line 46, in <module> 
         TagGrabber.run() 
         File "/tmp/test.root.20150520.071726.549519/job_local_dir/0/mapper/0/mrjob.tar.gz/mrjob/job.py", line 461, in run 
         mr_job.execute() 
         File "/tmp/test.root.20150520.071726.549519/job_local_dir/0/mapper/0/mrjob.tar.gz/mrjob/job.py", line 470, in execute 
         self.run_mapper(self.options.step_num) 
         File "/tmp/test.root.20150520.071726.549519/job_local_dir/0/mapper/0/mrjob.tar.gz/mrjob/job.py", line 535, in run_mapper 
         for out_key, out_value in mapper(key, value) or(): 
         File "/var/cc-mrjob/mrcc.py", line 33, in mapper 
         for i, record in enumerate(f): 
         File "/var/cc-mrjob/venv/local/lib/python2.7/site-packages/warc/warc.py", line 390, in __iter__ 
         record = self.read_record() 
         File "/var/cc-mrjob/venv/local/lib/python2.7/site-packages/warc/warc.py", line 373, in read_record 
         header = self.read_header(fileobj) 
         File "/var/cc-mrjob/venv/local/lib/python2.7/site-packages/warc/warc.py", line 331, in read_header 
         raise IOError("Bad version line: %r" % version_line) 
        IOError: Bad version line: 'WARC/1.0\n' 
    
  2. же, как # 1, но с tail команда

  3. же, как # 1, но используя tr или sed после замены любой утраченной новой строки или символов ^M (возврат каретки). Это приводит к тому, что пакет warc все еще жалуется на то, что ожидаемые возвращения каретки или новые строки не были на месте.
  4. unix2dos oldfile
+0

Глядя на warc python lib, он не читает весь файл .warc сразу, а записывает за один раз. Для чего вам требуется усечение? Честный вопрос, возможно, переезд по сети или какой-то такой? –

+0

Добавляя к предыдущему «он не читает весь .warc», довольно тривиально реализовать «читать N первых записей», используя только warc lib: 'islice (warc_file, N)', если это то, что вы ищете. –

+0

@ Илья спасибо - это именно то, что я искал. Можете ли вы добавить это как ответ? – okoboko

ответ

1

Было бы трудно правильно обрабатывать переводы строк, потому что .warc файлы могут содержать двоичные данные, а также. Усечение также, вероятно, приведет к повреждению файлов .warc, поскольку, например, библиотека python доверяет тому, что заголовки Content-Length действительны.

The warc python lib считывает только запись за один раз из файла .warc (избегая чтения всего файла в память сразу), и, таким образом, можно обрабатывать подмножества только с использованием только python. Например:

import warc 
from itertools import islice 

N = 10 
warc_file = warc.open('/path/to/file.warc') 
for record in islice(warc_file, N): 
    do_stuff_with(record) 
Смежные вопросы