#python #xml #web-scraping #beautifulsoup #tags
Вопрос:
Я пытаюсь получить текстовое содержимое тега «Идентификатор события» в XML, но дефис не распознается как элемент в файле, я знаю, что скрипт работает хорошо, потому что, если заменить дефис на подчеркивание в XML и запустить скрипт, он работает, кто-нибудь знает, в чем может быть проблема?
<?xml version="1.0" encoding="UTF-8"?>
<eventsUpdate xmlns="http://nateng.com/xsd/NETworks">
<fullEventsUpdate xmlns="">
<fullEventUpdate xmlns="">
<event-reference xmlns="">
<event-id xmlns="">24425412</event-id>
<event-update xmlns="">34</event-update>
</event-reference>
</fullEventUpdate>
<fullEventUpdate xmlns="">
<event-reference xmlns="">
<event-id xmlns="">24342548</event-id>
<event-update xmlns="">34</event-update>
</event-reference>
</fullEventUpdate>
</fullEventsUpdate>
</eventsUpdate>
from bs4 import BeautifulSoup
dir_path = '20211006085201.xml'
file = open(dir_path, encoding='UTF-8')
contents = file.read()
soup = BeautifulSoup(contents, 'xml')
events = soup.find_all('fullEventUpdate')
print(' n-------', len(events), 'events calculated on ', dir_path, '--------n')
idi = soup.find_all('event-reference')
for x in range(0, len(events)):
idText = (idi[x].event-id.get_text())
print(idText)
Ответ №1:
Проблема в том, что вы имеете дело с xml с пространством имен, и для этого типа документа вместо этого следует использовать селекторы css:
events = soup.select('fullEventUpdate')
for event in events:
print(event.select_one('event-id').text)
Выход:
24425412
24342548
В более общем плане, при работе с xml-документами вам, вероятно, лучше использовать что-то, что поддерживает xpath (например, lxml или ElementTree).
Ответ №2:
Для синтаксического анализа XML идиоматический подход заключается в использовании селекторов xpath.
В python это может быть легко достигнуто с parsel
помощью пакета, который аналогичен beautifulsoup
, но построен поверх lxml
для полной поддержки xpath:
body = ...
from parsel import Selector
selector = Selector(body)
for event in sel.xpath("//event-reference"):
print(event.xpath('event-id/text()').get())
результаты в:
24425412
24342548
Ответ №3:
Без какой-либо внешней библиотеки (только ElementTree)
import xml.etree.ElementTree as ET
xml = '''<?xml version="1.0" encoding="UTF-8"?>
<eventsUpdate xmlns="http://nateng.com/xsd/NETworks">
<fullEventsUpdate xmlns="">
<fullEventUpdate xmlns="">
<event-reference xmlns="">
<event-id xmlns="">24425412</event-id>
<event-update xmlns="">34</event-update>
</event-reference>
</fullEventUpdate>
<fullEventUpdate xmlns="">
<event-reference xmlns="">
<event-id xmlns="">24342548</event-id>
<event-update xmlns="">34</event-update>
</event-reference>
</fullEventUpdate>
</fullEventsUpdate>
</eventsUpdate> '''
root = ET.fromstring(xml)
ids = [e.text for e in root.findall('.//event-id')]
print(ids)
выход
['24425412', '24342548']