Только вставки кода недостаточно. Вы также должны объяснить, почему это работает :)

лил html через xpath, который затем преобразовал в etree. Что-то похожее на это:

<td> text1 <a> link </a> text2 </td>

но когда я вызываю element.text, я получаю только text1 (он должен быть там, когда я проверяю свой запрос в FireBug, текст элементов выделяется, как текст до, так и после встроенных якорных элементов ...

 user52203422 янв. 2011 г., 21:45
if element.tag == "td": children = element.getchildren () if len (children)> 0: topic = (element.text + children [0] .tail) else: topic = element.text print ("\ tTopic: \ t \ t% s "% topic)
 user52203422 янв. 2011 г., 21:44
Вот фрагмент кода:
 user52203422 янв. 2011 г., 21:44
Это один из способов сделать это (фрагмент кода из моего маленького обработчика Python Scrape). Интересно, если это ошибка lxml?

Ответы на вопрос(8)

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

from lxml import etree

def get_text1(node):
    result = node.text or ""
    for child in node:
        if child.tail is not None:
            result += child.tail
    return result

def get_text2(node):
    return ((node.text or '') +
            ''.join(map(get_text2, node)) +
            (node.tail or ''))

def get_text3(node):
    return (node.text or "") + "".join(
        [etree.tostring(child) for child in node.iterchildren()])


root = etree.fromstring(u"<td> text1 <a> link </a> text2 </td>")

print root.xpath("text()")
print get_text1(root)
print get_text2(root)
print root.xpath("string()")
print etree.tostring(root, method = "text")
print etree.tostring(root, method = "xml")
print get_text3(root)

Выход:

snowy:rpg$ python test.py 
[' text1 ', ' text2 ']
 text1  text2 
 text1  link  text2 
 text1  link  text2 
 text1  link  text2 
<td> text1 <a> link </a> text2 </td>
 text1 <a> link </a> text2 
<td> text1 <a> link </a> text2 </td>

Вот как это происходит (игнорируя пробелы):

td.text == 'text1'
a.text == 'link'
a.tail == 'text2'

Если вам не нужен текст внутри дочерних элементов, вы можете собрать только их хвосты:

text = td.text + ''.join([el.tail for el in td])

но в соответствии с дизайном, если вы читаете документацию. Я решил это так:

def node_text(node):
    if node.text:
        result = node.text
    else:
        result = ''
    for child in node:
        if child.tail is not None:
            result += child.tail
    return result
 mmj22 июл. 2016 г., 09:45
Это не ошибка, на самом деле это функция, которая позволяет вам вставлять текст между подэлементами при создании элемента XML:stackoverflow.com/q/38520331/694360
 Jaap Versteegh27 июл. 2016 г., 21:36
Спасибо что подметил это. Я думаю, это полезно, но имхо было бы намного яснее, если.text будет просто возвращать полный текст, а какое-то другое свойство с соответствующим именем будет содержать только часть до первого подэлемента. Как насчетnode.head, Это также дает ключ к пониманию того, что вам нужноchild.tail без необходимости в стеке потока

element.xpath("string()") или жеlxml.etree.tostring(element, method="text") - видетьдокументация.

 user52203424 янв. 2011 г., 08:38
element.text + child.tail работает, но я бы хотел, чтобы element.text работал так, как я хочу :)
 user52203424 янв. 2011 г., 08:51
element.xpath ("string ()") возвращает тот же результат, что и * .tostring (). Я попытался xpath ("text ()"), который не возвращает текст элемента привязки, но возвращает список из 2 строк. Спасибо, что указал на некоторые вещи, хотя.
 user52203424 янв. 2011 г., 08:36
toString (element, method = "text") почти работает, но он также возвращает текст встроенного элемента привязки, который я не хочу.
element.xpath('normalize-space()') also works.
 Robert Williams24 июл. 2017 г., 06:24
Только вставки кода недостаточно. Вы также должны объяснить, почему это работает :)
def get_text_recursive(node):
    return (node.text or '') + ''.join(map(get_text_recursive, node)) + (node.tail or '')

Еслиelement равно<td>, Вы можете сделать следующее.

element.xpath('.//text()')

Это даст вам список всех текстовых элементов изself (значение точки).// означает, что это займет все элементы и, наконец,text() это функция для извлечения текста.

которая, кажется, работает хорошо, чтобы получить текст из элемента, это"".join(element.itertext())

Ваш ответ на вопрос