На этом шаге мы рассмотрим использование модуля xml.etree.ElementTree.
Вы хотите извлечь данные из простого XML-документа.
Модуль xml.etree.ElementTree может быть использован для извлечения данных из простых XML-документов. Чтобы продемонстрировать это, предположим, что вы хотите распарсить и подготовить выжимку RSS-канала Planet Python.
https://planetpython.org/.
from urllib.request import urlopen from xml.etree.ElementTree import parse # Скачивание и парсинг RSS-канала u = urlopen('https://planetpython.org/rss20.xml') doc = parse(u) # Извлечение и вывод нужных тегов for item in doc.iterfind('channel/item'): title = item.findtext('title') date = item.findtext('pubDate') link = item.findtext('link') print(title) print(date) print(link) print()
Если вы запустите вышеприведенный скрипт, вывод будет примерно таким:
Steve Holden: Python for Data Analysis Mon, 19 Nov 2012 02:13:51 +0000 http://holdenweb.blogspot.com/2012/11/python-for-data-analysis.html Vasudev Ram: The Python Data model (for v2 and v3) Sun, 18 Nov 2012 22:06:47 +0000 http://jugad2.blogspot.com/2012/11/the-python-data-model.html Python Diary: Been playing around with Object Databases Sun, 18 Nov 2012 20:40:29 +0000 http://www.pythondiary.com/blog/Nov.18,2012/been-...-object-databases.html Vasudev Ram: Wakari, Scientific Python in the cloud Sun, 18 Nov 2012 20:19:41 +0000 http://jugad2.blogspot.com/2012/11/wakari-scientific-python-in-cloud.html Jesse Jiryu Davis: Toro: synchronization primitives for Tornado coroutines Sun, 18 Nov 2012 20:17:49 +0000 http://feedproxy.google.com/~r/EmptysquarePython/~3/_DOZT2Kd0hQ/
Очевидно, что если вы хотите провести дополнительную обработку, вам нужно заменить инструкции print() на что-то более интересное.
В очень многих приложениях нужно работать с XML-данными. XML не только широко используется в качестве формата для обмена данными через интернет, это также распространенный формат хранения данных приложений (обработка текста, музыкальные библиотеки и т. п.). Следующее обсуждение подразумевает, что вы уже знакомы с основами XML.
Во многих случаях, когда XML просто используется для хранения данных, структура документа проста и прямолинейна. Например, RSS-поток из примера выглядит примерно так:
<?xml version="1.0"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<title>Planet Python</title>
<link>http://planet.python.org/</link>
<language>en</language>
<description>Planet Python - http://planet.python.org/</description>
<item>
<title>Steve Holden: Python for Data Analysis</title>
<guid>http://holdenweb.blogspot.com/...-data-analysis.html</guid>
<link>http://holdenweb.blogspot.com/...-data-analysis.html</link>
<description>...</description>
<pubDate>Mon, 19 Nov 2012 02:13:51 +0000</pubDate>
</item>
<item>
<title>Vasudev Ram: The Python Data model (for v2 and v3)</title>
<guid>http://jugad2.blogspot.com/...-data-model.html</guid>
<link>http://jugad2.blogspot.com/...-data-model.html</link>
<description>...</description>
<pubDate>Sun, 18 Nov 2012 22:06:47 +0000</pubDate>
</item>
<item>
<title>Python Diary: Been playing around with Object Databases</title>
<guid>http://www.pythondiary.com/...-object-databases.html</guid>
<link>http://www.pythondiary.com/...-object-databases.html</link>
<description>...</description>
<pubDate>Sun, 18 Nov 2012 20:40:29 +0000</pubDate>
</item>
...
</channel>
</rss>
Функция xml.etree.ElementTree.parse() парсит весь XML-документ в объект document. Далее вы можете использовать такие методы, как find(), iterfind() и findtext(), для поиска определенных XML-элементов. Аргументы этих функций - это имена определенных тегов, такие как channel/item или title.
Когда вы задаете теги, то должны принимать во внимание всю структуру документа. Каждая операция поиска предпринимается относительно стартового элемента. Тег, который вы предоставляете каждой операции, также рассматривается относительно старта. В вышеприведенном примере вызов doc.iterfind('channel/ item') найдет все элементы "item" под элементом "channel". doc представляет вершину документа (высший уровень - элемент "rss"). Последующие вызовы item.findtext() будут делаться относительно найденных элементов "item".
Каждый элемент, представленный модулем ElementTree, имеет несколько основных атрибутов и методов, весьма полезных при парсинге. Атрибут tag содержит имя тега, атрибут text содержит прилагаемый текст, а метод get() может быть использован для извлечения атрибутов (если они присутствуют). Например:
>>> doc <xml.etree.ElementTree.ElementTree object at 0x101339510> >>> e = doc.find('channel/title') >>> e <Element 'title' at 0x10135b310> >>> e.tag 'title' >>> e.text 'Planet Python' >>> e.get('some_attribute') >>>
Стоит отметить, что xml.etree.ElementTree - не единственный способ парсинга XML. Для более продвинутых приложений вы можете попробовать lxml.
https://pypi.org/project/lxml/.
Эта библиотека использует тот же интерфейс, что и ElementTree, так что вышеприведенные примеры будут работать так же. Вы просто должны изменить первую инструкцию import на from lxml.etree import parse. Библиотека lxml имеет преимущество - полное соответствие стандартам XML. Она также чрезвычайно быстро работает и предоставляет поддержку таких возможностей, как валидация, XSLT и XPath.
На следующем шаге мы рассмотрим пошаговый парсинг очень больших XML-файлов.