2011-01-22 12 views
10

से वापस नहीं करता है, मैंने xpath के माध्यम से कुछ HTML को तोड़ दिया, जिसे मैंने फिर एक एट्री में परिवर्तित कर दिया। इस के लिए कुछ इसी तरह की:lxml.etree, element.text पूरे पाठ को तत्व

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

लेकिन जब मैं element.text कहते हैं, मैं सिर्फ टेक्स्ट 1 मिलता है (यह, वहाँ होना चाहिए जब मैं FireBug में अपनी क्वेरी की जाँच करें, तत्वों के पाठ पर प्रकाश डाला है, दोनों से पहले पाठ और एम्बेडेड लंगर तत्वों के बाद ...

+0

यह करने का एक तरीका है (मेरे छोटे पायथन स्क्रैप प्रोसेसर से कोड स्निपेट)। आश्चर्य है कि यह एक एलएक्सएमएल बग है? – user522034

+0

यहाँ कोड का टुकड़ा है: – user522034

+0

अगर element.tag == "td": \t \t \t \t बच्चों = element.getchildren() \t \t \t \t अगर (बच्चों) लेन> 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 प्रिंट ("\ tTopic: \ t \ t% s"% विषय) – user522034

उत्तर

15

उपयोग element.xpath("string()") या lxml.etree.tostring(element, method="text") -।। the documentation देख

+0

टूस्ट्रिंग (तत्व, विधि = "पाठ") लगभग काम करता है, लेकिन यह एम्बेडेड एंकर तत्व का पाठ भी देता है, जिसे मैं नहीं चाहते – user522034

+0

element.text + child.tail काम करता है, लेकिन मेरी इच्छा है element.text जिस तरह से मैं चाहता हूं :) – user522034

+0

element.xpath ("string()") * .tostring() के समान परिणाम देता है। मैंने xpath ("text()") की कोशिश की जो एंकर तत्व के पाठ को वापस नहीं करता है, लेकिन यह 2 तारों की एक सूची देता है। यद्यपि कुछ सामान इंगित करने के लिए धन्यवाद। – user522034

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

यह एक बग नहीं है, असल में यह सुविधा है जो आपको XML तत्व बनाने के दौरान उपखंडों के बीच पाठ को स्थानांतरित करने की अनुमति देती है: http://stackoverflow.com/q/38520331/694360 – mmj

+0

यह इंगित करने के लिए धन्यवाद। मुझे लगता है कि यह उपयोगी है, लेकिन imho यह बहुत स्पष्ट होगा अगर '.text' सिर्फ पूर्ण पाठ वापस कर देगा और कुछ अन्य उपयुक्त नामित संपत्ति में केवल पहले उप-भाग में हिस्सा होगा। 'Node.head' के बारे में कैसे। यह एक सुराग भी देता है कि आप जो चाहते हैं वह पहले 'stackoverflow' के बिना 'child.tail' है। –

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. 
+3

केवल कोड चिपकाना पर्याप्त नहीं है। आपको यह भी समझाया जाना चाहिए कि यह क्यों काम करता है :) –

संबंधित मुद्दे