Анализ содержимого lxml.etree._Element

У меня есть следующий элемент, который я обработал из <table>

 <td align="center" valign="top"> <a href="ConfigGroups.aspx?cfgID=451161&amp;prjID=11778&amp;grpID=DTST" target="_blank"> 5548U </a><br/>Power La Vaca<br/>(M8025K)<br/>Linux 4.2.xx<br/> </td> 

Я пытаюсь извлечь из этого элемента «55488 Power La Vaca (8025K) Linux 4.2.xx» (включая пробелы).

 import lxml.etree as ET td_html = """ <td align="center" valign="top"> <a href="ConfigGroups.aspx?cfgID=451161&amp;prjID=11778&amp;grpID=DTST" target="_blank"> 5548U </a><br/>Power La Vaca<br/>(M8025K)<br/>Linux 4.2.xx<br/> </td> """ td_elem = ET.fromstring(td_html) fail_1 = td_elem.find('a').text + td_elem.text print "FAIL_1", fail_1 print "FAIL_2" for elem in td_elem.iterchildren(): print elem.tag, elem.text 

Результаты

 $ python textxml.py FAIL_1 5548U FAIL_2 a 5548U br None br None br None br None $ 

Вопрос

Смирение, что я должен задать этот вопрос, поскольку это не похоже, что это должно быть сложно.

Как я могу извлечь «Power La Vaca (8025K) Linux 4.2.xx» из элемента td_elem (включая пробелы)?

Пожалуйста, никаких регулярных выражений.

Решение

Явное решение (с использованием предложения Finn от itertext() ):

 import lxml.etree as ET td_html = """ <td align="center" valign="top"> <a href="ConfigGroups.aspx?cfgID=451161&amp;prjID=11778&amp;grpID=DTST" target="_blank"> 5548U </a><br/>Power La Vaca<br/>(M8025K)<br/>Linux 4.2.xx<br/> </td> """ td_elem = ET.fromstring(td_html) print "SUCCESS", ' '.join([txt.strip() for txt in td_elem.itertext()]) 

Я знаю, что должен быть лучший способ, но это работает.

 link = td_elem.find('a').text.strip() text = ''.join(td_elem.itertext()).strip() text.split(link)[1] 

Выход – Power La Vaca (M8025K) Linux 4.2.xx

Обновление: на самом деле это лучше, если вы хотите, чтобы вместо тех,

 ' '.join(map(str, [el.tail for el in td_elem.iterchildren() if el.tail])) 

map str самом деле не нужна для этого, но я могу представить себе другие значения, для которых она была бы.

При работе с XML, даже в Python, мне нравится пытаться использовать доступные для домена инструменты. Для разбора битов XML XPath это для меня.

 >>> td_elem = ET.fromstring(td_html) >>> >>> # Use XPath to grab just the text nodes under <td/>, >>> # ignoring any text nodes in child nodes of <td/> (ie, <a...>5548U</a>) >>> print(td_elem.xpath('/td/text()')) ['\n ', 'Power La Vaca', '(M8025K)', 'Linux 4.2.x.x', '\n'] >>> >>> # Make it a little cleaner >>> ' '.join(x.strip() for x in td_elem.xpath('/td/text()')) ' Power La Vaca (M8025K) Linux 4.2.xx ' >>> >>> # Just for reference, grab all text nodes with '//' >>> ' '.join(x.strip() for x in td_elem.xpath('/td//text()')) ' 5548U Power La Vaca (M8025K) Linux 4.2.xx '