2011-01-22 19 views
10

öğesinden tüm metni geri döndürmez. Xpath yoluyla bazı html'yi kopyaladıktan sonra bir etiğe dönüştürdüm. Buna benzer bir şey:lxml.etree, element.text,

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

Ben FireBug benim sorgu kontrol ederken ama element.text çağırdığınızda, sadece metin1 olsun (O olmalı, elemanların metin vurgulanır, önce metin hem ve gömülü ankraj elemanları sonra ...

+0

Bunu yapmanın bir yolu budur (küçük python kazıyıcı işlemciden kod parçacığı). Bu bir lxml hatası mı merak ediyorum? – user522034

+0

İşte kod snippet'ine: – user522034

+0

eğer element.tag == "td": \t \t \t \t çocuk = element.getchildren() \t \t \t \t eğer len (çocuk)> 0: \t \t \t \t \t topic = (element.text + çocuk [0] .tail) başka \t \t \t \t: \t \t \t \t \t başlık = eleme nt.text \t \t \t \t print ("\ tTopic: \ t \ t% t"% topic) – user522034

cevap

15

kullanın element.xpath("string()") veya lxml.etree.tostring(element, method="text") -.. the documentation bakınız

+0

toString (öğe, method = "text") hemen hemen çalışır, ancak aynı zamanda gömülü anchor öğesinin metnini de döndürür. istemiyorum – user522034

+0

element.text + child.tail çalışır, ancak keşke element.text istediğim şekilde çalışmasını isterdim :) – user522034

+0

element.xpath ("string()"), * .tostring() ile aynı sonucu verir. Anchor öğesinin metnini döndürmeyen xpath ("text()") denedim, ancak 2 dizenin bir listesini döndürür. Yine de bazı şeyleri işaretlediğiniz için teşekkürler. – user522034

5

bana bir lxml hata gibi görünüyor, ama belgelere okursanız tasarımına göre ben böyle çözdük :

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

Bu bir hata değil, aslında bir XML öğesi oluştururken alt bağlantılar arasında metin aramanıza olanak veren özellik: http://stackoverflow.com/q/38520331/694360 – mmj

+0

Bunu işaretlediğiniz için teşekkürler. Sanırım bu yararlıdır, ancak .txt 'tam metnini döndürürse ve diğer uygun şekilde adlandırılmış mülkler yalnızca ilk ikincisine kadar olan kısmı içerdiğinde çok daha açık olacaktır. 'Node.head' hakkında ne dersiniz? Bu, bir sonraki adımda, ilk önce stackoverflow uygulamasına gerek kalmadan "child.tail" öğesinin ne olacağına dair bir ipucu verir. –

1
def get_text_recursive(node): 
    return (node.text or '') + ''.join(map(get_text_recursive, node)) + (node.tail or '') 
5

Dışarıdaki gibi tembel olabilecek insanlara bir kamu hizmeti olarak. İşte baştan başlayabileceğiniz bazı kodlar.

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) 

Çıktı geçerli:

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 
İşte
1
<td> text1 <a> link </a> text2 </td> 

o (gözardı boşluk) 'dir açıklanmıştır:

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

sonra alt öğeleri içinde olan bir metin istemiyorsanız Yalnızca kendi kuyruklarını toplayabilirsiniz:

<td> eşitse
3

bir elementin dışında metnini almak için iyi çalışıyor gibi görünüyor başka bir şey "".join(element.itertext())

0

olduğunu. Aşağıdakileri yapabilirsiniz.

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

Size self gelen tüm metin öğelerinin bir listesini (noktanın anlamı) verecektir. //, tüm öğeleri alacağı ve son olarak text() metnin çıkarılacağı anlamına gelir.

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

Sadece yapıştırma kodu yeterli değil. Neden çalıştığını da açıklamalısınız :) –