#python #xml #beautifulsoup
#python #xml #beautifulsoup
Вопрос:
Я пытаюсь использовать BeautifulSoup для анализа некоторого XML, который выглядит как
<a>
<b>
<c>
<d attr="x">
<e>
</e>
<name>
</name>
</d>
</c>
<c>
...
<c>
</b>
</a>
но я не могу понять, как получить доступ к e
or name
в цикле. Это работает:
print soup.a.b.c.d.e
но это не:
for subtag in soup.a.b.c:
print subtag.d.e
вместо этого он выдает эту ошибку:
AttributeError: 'NavigableString' object has no attribute 'd'
и, что несколько не связано, это:
print soup.a.b.c.d.name
только выходные данные d
.
Что я делаю не так? Я подозреваю, что для второй проблемы мне придется использовать find()
вместо этого, потому что у этого объекта уже есть name
атрибут. Есть ли более приятный способ?
Комментарии:
1. Какова цель этого синтаксического анализа? Вы привязываетесь к извлечению первого
e
элемента каждогоd
элемента, содержащегося в первомa.b.c
элементе?2. Я хочу, чтобы все (
d
,e
,name
) группы.
Ответ №1:
Вы получаете, AttributeError
потому что BSS возвращает NavigableString
s при циклическом переборе Tag
экземпляров. Может быть, вы хотите попробовать:
soup.a.b.c.findChildren()
#[<d attr="x">
#<e>
#</e>
#<name>
#</name>
#</d>, <e>
#</e>, <name>
#</name>]
Что касается проблемы с name
: она указана как атрибут, но вместо этого вы можете сделать:
soup.a.b.c.d.findChildren('name')
#[<name>
#</name>]
Установочный код для справки:
from BeautifulSoup import BeautifulStoneSoup as bss
soup = bss(markup)
Ответ №2:
это:
print soup.a.b.c.d.name
выводит только d.
Это происходит потому, что name
конфликтует со встроенным name
атрибутом объектов тегов. Согласно документации по использованию имен тегов в качестве членов, вы можете использовать soup.a.b.c.d.nameTag
вместо этого.
Ошибка атрибута хорошо объяснена в других ответах. Если вы хотите извлечь каждую (d, e, name)
тройку во всем документе, независимо от того, где появляется d
тег, вы могли бы сделать что-то вроде этого:
soup = BeautifulStoneSoup(doc)
for d in soup.findAll('d'):
print (d, d.e, d.nameTag)