[prg] Python: ZIP+ElementTree+FB2.
Здравствуйте.
Python 3.6
Win7
Возник тут у меня один вопрос. Я занимаюсь парсингом FB2-книг. При
этом использую класс ElementTree. Все замечательно, кроме нескольких
моментов. об ошибке ParseError на файлах CP1251 с некоторыми символами
как-нибудь в другой раз, а пока остановлюсь на проблеме анализа FB2 в
архивах.
Суть в следующем, я очень не хочу распаковывать файлы на диск. Ну в
самом-то деле, файлов этих у меня сотни тысяч...
А вот как сделать файловый объект в оперативной памяти, никак не
соображу.
Вышел из положения при помощи функции read объекта ZipFile. Передавая
ей имя анализируемого файла:
zf.read(fn)
На выходе получается байтовая строка, которую скармливаю функции
fromstring класса ElementTree.
В общем-то работает. Но ненадёжно к сожалению. Некоторые файлы таким
образом распарсить не получается. Исследования показали, что
fromstring почему-то теряет тег fictionbook, и возвращает список из
description и body.
Ну и вообще - получается объект element, а не ElementTree... Это тоже
как-то мне кажется неэстетичным.
В общем, хочу распаковать файл из архива в какую-нибудь переменную,
которую можно скормить ElementTree... Создавать что-либо на диске
не хочу категорически.
В общем, можно ли это как-то реализовать?
Если кто захочет поиграться, с удовольствием предоставлю и код и
битый файл.
Буду благодарен за любую помощь.
И позволю уж себе немножко поныть... :-)
Всегда казалось, что работа с zip-архивами - это одна из
востребованных практических задач при написании программ. В то же
время модуль zipfile производит впечатление какого-то уж больно
куцего, особенно, если сравнить с функционалом графических
архиваторов. Например, я так и не смог сообразить, как можно
переименовать файл в архиве... Кстати, как-то совершенно не смог
скормить функции по упаковке параметр compression.
compression=ZIP_DEFLATE Python воспринимать не захотел от слова
совсем. Я даже в исходниках нашёл, как он там пишется, но так и
пришлось использовать цифровое значение нужного параметра...
В общем, Python, на первый взгляд кажется просто замечательным, но при
попытке решить какую-нибудь задачу, слегка выходящую за пределы
стандарта, постоянно сталкиваешься с какими-то непонятками, с которыми
неизвестно что делать.
Наверное, так и придется взять мозги в кулак и выучить плюсы...
Приветствую всех!
Устарел. Надо использовать xml.etree.cElementTree (это тот же API, но
реализован на C).
Не советую пренебрегать чтением документации. Это и есть штатное поведение
указанного метода: fromstring сразу возвращает корневой Element, а не
ElementTree.
Добавьте print и убедитесь:
root = et.fromstring(b)
print (root.tag)
Использование C++ для подобных задач -- похоже на использование самурайского
меча для заточки карандашей. Всё-таки для этого лучше использовать
карандашную точилку -- и безопасней, и результат можно получить с меньшими
усилиями.
К тому же, обсуждаемая проблема не имеет отношения к используемому языку
программирования, а связана с библиотеками тех или иных API. В C++ вам тоже
придётся разбираться с ними, но только код не будет таким прозрачным и
простым, как в python.
Успехов. Анатолий.