Skip to content

Add easy way to iterate over warc records #14

Description

@sirex

I was surprised that example provided in documentation:

>>>importwarcat.model>>>warc=warcat.model.WARC()
>>>warc.load('example/at.warc.gz')
>>>len(warc.records)

Reads everything into memory. And there is no easy way to iterate over records without loading everything into memory.

In my case, WARC files takes gigabytes of space, so I want to process those files record by record without loading everything into memory.

After reading sources I came up with this helper function:

importwarcat.modeldefreadwarc(filename, types=('response',)):
f=warcat.model.WARC.open(filename)
has_more=Truewhilehas_more:
record, has_more=warcat.model.WARC.read_record(f)
ifnottypesorrecord.warc_typeintypes:
ifisinstance(record.content_block, warcat.model.BlockWithPayload):
yieldrecord, record.content_block.payload.get_fileelifhasattr(record.content_block, 'binary_block'):
yieldrecord, record.content_block.binary_block.get_fileelse:
yieldrecord, record.content_block.get_fileforrecord, contentinreadwarc('pages.warc.gz'):
withcontent() asf:
# process f

I think it would be really useful if Warcat would provide an interface for lazy iteration over whole WARC file. I would image it to look something like this:

importwarcatforrecordinwarcat.readrecords('pages.warc.gz'):
withrecord.content() asf:
# process f

Also, if I could get lxml, BeautifulSoap and json from records, something like this:

forrecordinwarcat.readrecords('pages.warc.gz'):
record.lxml.xpath('//a')
record.soap.select('a')
record.json['a']

Then it would be really amazing.

If you agree with suggested API, I can create pull request with the implementation.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions