2011-01-22 26 views
10

我通過xpath刪除了一些html,然後轉換爲etree。一些與此類似:lxml.etree,element.text不會返回元素的全部文本

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

,但是當我打電話element.text,我只得到text1的(它必須在那裏,當我檢查我的螢火查詢,該元素的文本被高亮顯示,無論是之前的文本和嵌入式錨元素之後...

+0

這是一種方法(從我的小python刮處理器代碼片段)。不知道這是一個lxml錯誤嗎? – user522034 2011-01-22 20:44:28

+0

下面的代碼片段: – user522034 2011-01-22 20:44:53

+0

如果element.tag == 「TD」: \t \t \t \t孩子= element.getchildren() \t \t \t \t如果len(兒童)> 0: \t \t \t \t \t話題= (element.text +兒童[0] .tail) \t \t \t \t否則: \t \t \t \t \t主題= eleme NT。文本 \t \t \t \t print(「\ tTopic:\ t \ t%s」%topic) – user522034 2011-01-22 20:45:31

回答

15

使用element.xpath("string()")lxml.etree.tostring(element, method="text") - 見the documentation

+0

toString(element,method =「text」)幾乎可行,但它也返回嵌入式錨元素的文本,不想要。 – user522034 2011-01-24 07:36:03

5

看起來像一個LXML錯誤給我,但根據如果你閱讀文檔,設計我已經解決它像這樣:

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 
1
def get_text_recursive(node): 
    return (node.text or '') + ''.join(map(get_text_recursive, node)) + (node.tail or '') 
5

作爲一種公共服務給那些可能像我一樣懶惰的人。這裏有一些你可以運行的代碼。

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("string()") 
print root.xpath("text()") 
print get_text1(root) 
print get_text2(root) 
print etree.tostring(root, method = "text") 
print etree.tostring(root, method = "xml") 
print get_text3(root) 

輸出是:

snowy:rpg$ python test.py 
text1 link text2 
[' text1 ', ' text2 '] 
text1 text2 
text1 link text2 
text1 link text2 
<td> text1 <a> link </a> text2 </td> 
text1 <a> link </a> text2 
1
<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]) 
3

似乎運作良好,以獲得從文本元素的另一件事是"".join(element.itertext())

0

如果element等於<td>。您可以執行以下操作。

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

它會給你所有文本元素的從self列表(點的意思)。 //表示它將採用所有元素,最後是text()是提取文本的函數。

0
element.xpath('normalize-space()') also works.