2009-10-16 7 views
20

Tôi đang tìm kiếm trong tài liệu HTML sử dụng XPath từ lxml trong python. Làm thế nào tôi có thể nhận được đường dẫn đến một yếu tố nhất định? Dưới đây là các ví dụ từ ruby ​​nokogiri:Cách lấy đường dẫn của phần tử trong lxml?

page.xpath('//text()').each do |textnode| 
    path = textnode.path 
    puts path 
end 

in ví dụ '/html/body/div/div [1]/div [1]/p/text() [1]' và đây là chuỗi Tôi muốn nhận được trong python.

Trả lời

38

Sử dụng getpath từ các đối tượng ElementTree.

from lxml import etree 

root = etree.fromstring('<foo><bar>Data</bar><bar><baz>data</baz>' 
         '<baz>data</baz></bar></foo>') 

tree = etree.ElementTree(root) 
for e in root.iter(): 
    print tree.getpath(e) 

Prints

/foo 
/foo/bar[1] 
/foo/bar[2] 
/foo/bar[2]/baz[1] 
/foo/bar[2]/baz[2] 
+0

Tôi nghĩ rằng nó phải là 'cho e trong tree.iter():', tức là ** cây **. – Jabba

+1

@Jabba Và tại sao bạn lại nghĩ vậy? Bạn đã thử mã tôi đã cung cấp theo cách chưa? Dường như nó hoạt động, phải không? Bạn có lý do ** để suy nghĩ khác không? – nosklo

+0

Nó có thể đã không tồn tại khi bạn đã viết này ban đầu và không phải là nó thực sự quan trọng, nhưng bạn cũng có thể làm 'tree = root.getroottree()' để có được một đối tượng ElementTree. –

17

Xem Xpath and XSLT with lxml from the lxml documentation này cung cấp cho các con đường của nguyên tố này có chứa có văn bản

Một ví dụ sẽ

import cStringIO 
from lxml import etree 

f = cStringIO.StringIO('<foo><bar><x1>hello</x1><x1>world</x1></bar></foo>') 
tree = lxml.etree.parse(f) 
find_text = etree.XPath("//text()") 

# and print out the required data 
print [tree.getpath(text.getparent()) for text in find_text(tree)] 

# answer I get is 
>>> ['/foo/bar/x1[1]', '/foo/bar/x1[2]'] 
3
root = etree.parse(open('tmp.txt')) 

for e in root.iter(): 
    print root.getpath(e) 
2

Nếu tất cả các bạn h ave trong phần mã của bạn là phần tử và bạn muốn xpath của phần tử làm sau đó element.getroottree().getpath(element) sẽ thực hiện công việc.

from lxml import etree 

xml = ''' 
<test> 
    <a/> 
    <b> 
     <i/> 
     <ii/> 
    </b> 
</test> 
''' 
tree = etree.fromstring(xml) 

for element in tree.iter(): 
    print element.getroottree().getpath(element)