Я пытаюсь проанализировать файл dblp.xml (3,2 ГБ), используя lxml. Ниже приведен мой код.
from lxml import etree
from io import StringIO, BytesIO
tree = etree.parse("dblp.xml")
Однако я получаю сообщение об ошибке:
OSError Traceback (most recent call last)
<ipython-input-5-6a342013a160> in <module>
1 from lxml import etree
2 from io import StringIO, BytesIO
----> 3 tree = etree.parse("dblp.xml")
src/lxml/etree.pyx in lxml.etree.parse()
src/lxml/parser.pxi in lxml.etree._parseDocument()
src/lxml/parser.pxi in lxml.etree._parseDocumentFromURL()
src/lxml/parser.pxi in lxml.etree._parseDocFromFile()
src/lxml/parser.pxi in lxml.etree._BaseParser._parseDocFromFile()
src/lxml/parser.pxi in lxml.etree._ParserContext._handleParseResultDoc()
src/lxml/parser.pxi in lxml.etree._handleParseResult()
src/lxml/parser.pxi in lxml.etree._raiseParseError()
OSError: Error reading file 'dblp.xml': failed to load external entity "dblp.xml"
И dblp.xml, и dblp.dtd уже находятся в корневой папке.
Пожалуйста помоги!
2 ответа
Вы можете использовать etree.iterparse
, чтобы избежать загрузки всего файла. в памяти:
events = ("start", "end")
with open("dblp.xml", "r") as fo:
context = etree.iterparse(fo, events=events)
for action, elem in context:
# Do something
Это позволит вам извлекать только те объекты, которые вам нужны, игнорируя другие.
Как заявил Ян Яап Мейеринк, вы можете попробовать использовать iterparse. Возможно, вы также можете отключить функции безопасности lxml, предотвращающие синтаксический анализ огромных файлов (см. документацию по адресу https: //lxml.de/api/lxml.etree.XMLParser-class.html):
with open('', 'r') as fobj:
for event, elem in etree.iterparse(
fobj,
huge_tree=True,
):
#do something with element or event
В конце концов, если вы предпочитаете попробовать использовать синтаксический анализ, вы можете определить синтаксический анализатор xml с включенным huge_tree и установить его по умолчанию для дальнейшего использования etree.parse:
xml_parser_settings = dict(
huge_tree=True, # resolve_entities=False, remove_pis=True, no_network=True
)
XMLPARSER = etree.XMLParser(xml_parser_settings)
etree.set_default_parser(XMLPARSER)
После этих операторов вы можете использовать etree.parser с настроенным XMLPARSER. Однако остерегайтесь многопоточности (https://lxml.de/1.3/ api/lxml.etree-module.html#set_default_parser).
Добавление ключевого слова resolve_entities, remove_pis и no_network может (по крайней мере, немного) снизить риск парсинга огромных внешних файлов, если они исходят из ненадежного источника.
Похожие вопросы
Новые вопросы
python
Python — это мультипарадигмальный многоцелевой язык программирования с динамической типизацией. Он предназначен для быстрого изучения, понимания и использования, а также обеспечивает чистый и унифицированный синтаксис. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Если у вас есть вопросы о версии Python, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas, NumPy) укажите это в тегах.
dblp.xml
правильный? Возможно, вы захотите использовать полный путь, чтобы быть уверенным.