Python — как читать большие XML файлы при ограничении оперативной памяти
Рассмотрим на конкретном примере, как обработать большой каталог книг в формате XML размером 3 Гб.
Задача: скачать каталог по ссылке https://www.litres.ru/static/ds/detailed_data.xml.gz и узнать количество книг в каталоге.
Предварительно я скачал архив с xml и изучил, в каком теге лежит информация о книге. Это тег “art”. Теперь нам нужно написать скрипт, который найдёт все узлы с тегом “art” и посчитать их количество.
Для разбора xml используем встроенную библиотеку xml.etree.ElementTree
.
import xml.etree.ElementTree as ET
books = 0
for (event, node) in ET.iterparse('detailed_data.xml', events=['end']):
if node.tag == "art" and event == "end":
books += 1
node.clear()
print(books)
Всего получилось 1 051 440 книг.
Как работает модуль iterparse()
— постепенно проходит по xml-дереву элементов и возвращает два значения: событие event
и узел с данными node
.
Есть шесть событий events
, но мы рассмотрим только два:
- start – найден открывающий тег <node>
- end – найден закрывающий тег </node>
В данной задаче нас интересует событие end
, поэтому мы его и передали в параметры iterparse events=['end']
. То есть, если мы находим закрывающий тег “art”, то увеличиваем значение books на единицу. После этого указываем команду node.clear()
, чтобы освободить оперативную память от этого узла и работаем дальше.
Собственно весь секрет обработки больших xml файлов заключается в том, чтобы загружать в оперативную память только небольшой кусочек файла и после обработки – удалять его из памяти и переходить к следующему.