Python'da Xpath nasıl kullanılır?


224

Xpath'ı destekleyen kütüphaneler nelerdir? Tam bir uygulama var mı? Kütüphane nasıl kullanılır? Web sitesi nerede?


4
Bu sorunun cevabının şimdi biraz bayat olduğuna dair sinsi bir şüphem var.
Warren P

4
@ Gringo-suave'in yanıtı iyi bir güncellemeye benziyor. stackoverflow.com/a/13504511/1450294
Michael Scheper

Scrapy, XPath seçicileri sunar .
cs95

@ WarrenP'in dediği gibi, buradaki cevapların çoğu son derece eski, Python-2.x, gerçekten güncel değil. Belki de bu soru etiketlenmiş olmalıdır python-2.x
smci

Yanıtlar:


129

libxml2'nin birçok avantajı vardır:

  1. Spesifikasyonlara uygunluk
  2. Aktif gelişme ve topluluk katılımı
  3. Hız. Bu gerçekten bir C uygulaması etrafında bir python sarıcı.
  4. Ubiquity. Libxml2 kütüphanesi yaygındır ve bu nedenle iyi test edilmiştir.

Dezavantajları şunları içerir:

  1. Şartnameye uygunluk . Çok katı. Varsayılan ad alanı kullanımı gibi şeyler diğer kütüphanelerde daha kolaydır.
  2. Yerel kod kullanımı. Bu, uygulamanızın nasıl dağıtıldığı / dağıtıldığınıza bağlı olarak bir acı olabilir. Bu ağrının bir kısmını hafifleten RPM'ler mevcuttur.
  3. Manuel kaynak kullanımı. Aşağıdaki örnekte freeDoc () ve xpathFreeContext () çağrılarına dikkat edin. Bu çok Pythonic değil.

Basit yol seçimi yapıyorsanız, ElementTree (Python 2.5'e dahil olan) ile devam edin. Tam spesifikasyona veya ham hıza ihtiyacınız varsa ve yerel kodun dağıtımıyla başa çıkabiliyorsanız, libxml2 ile devam edin.

Libxml2 XPath Kullanımı Örneği


import libxml2

doc = libxml2.parseFile("tst.xml")
ctxt = doc.xpathNewContext()
res = ctxt.xpathEval("//*")
if len(res) != 2:
    print "xpath query: wrong node set size"
    sys.exit(1)
if res[0].name != "doc" or res[1].name != "foo":
    print "xpath query: wrong node set value"
    sys.exit(1)
doc.freeDoc()
ctxt.xpathFreeContext()

ElementTree XPath Kullanımı Örneği


from elementtree.ElementTree import ElementTree
mydoc = ElementTree(file='tst.xml')
for e in mydoc.findall('/foo/bar'):
    print e.get('title').text


8
osx üzerinde python 2.7.10 kullanarak ElementTree almak zorundafrom xml.etree.ElementTree import ElementTree
Ben Page

bir C sarıcı olduğu için, bir EC2 örneğinde veya AWS Linux'un Docker görüntüsünde derlemediğiniz sürece AWS Lambda'ya dağıtmakta zorluk
yaşayabilirsiniz

85

Lxml paket destekleri XPath. Ben kendi ekseni ile bazı sorun vardı rağmen, oldukça iyi çalışıyor gibi görünüyor. Orada da var Amara , ama ben şahsen kullanmadım.


1
amara çok hoş ve biri her zaman xpath'a ihtiyaç duymaz.
gatoatigrado

Lütfen XPath'ı lxml ile nasıl kullanacağınıza ilişkin bazı temel ayrıntıları ekleyin.
jpmc26

56

Burada bir lxml reklamı gibi görünüyor. ;) ElementTree, std kütüphanesine dahil edilmiştir. 2.6 altında ve altında xpath oldukça zayıf, ama 2.7 + 'da çok gelişmiş :

import xml.etree.ElementTree as ET
root = ET.parse(filename)
result = ''

for elem in root.findall('.//child/grandchild'):
    # How to make decisions based on attributes even in 2.6:
    if elem.attrib.get('name') == 'foo':
        result = elem.text
        break

39

LXML kullanın. LXML, libxml2 ve libxslt'nin tam gücünü kullanır, ancak bunları bu kütüphanelere özgü Python bağlarından daha "Pythonic" bağlarına sarar. Bu nedenle, tam XPath 1.0 uygulamasını alır. Yerel ElemenTree, gereksinimleriniz için yeterince iyi olsa da, sınırlı bir XPath alt kümesini destekler.


29

Başka bir seçenek py-dom-xpath , minidom ile sorunsuz bir şekilde çalışır ve saf Python'dur, bu nedenle appengine üzerinde çalışır.

import xpath
xpath.find('//item', doc)

2
Zaten minidom ile çalışıyorsanız lxml ve libxml2'den daha kolay. Güzel çalışır ve daha "Pythonic" dir. contextİçinde findişlevin yeni bir arama bağlam gibi başka bir xpath sonucu kullanalım.
Ben

3
Ben de bir eklenti yazarken py-dom-xpath kullanıyorum, çünkü saf python. Ama artık korunduğunu düşünmüyorum ve bu hatanın farkındayım ("Adı 'metin' olan bir öğeye erişilemiyor"): code.google.com/p/py-dom-xpath/issues/detail?id = 8
Jon Coombs

py-dom-xpath yıllar önce 2010 yılında güvensiz görünüyor , lütfen en azından bunu cevabınızda düzenleyin.
smci

14

Kullanabilirsiniz:

PyXML :

from xml.dom.ext.reader import Sax2
from xml import xpath
doc = Sax2.FromXmlFile('foo.xml').documentElement
for url in xpath.Evaluate('//@Url', doc):
  print url.value

libxml2 :

import libxml2
doc = libxml2.parseFile('foo.xml')
for url in doc.xpathEval('//@Url'):
  print url.content

Ben PyXML kodu deneyin, ben got ImportError: No module named extdenfrom xml.dom.ext.reader import Sax2
Aminah Nuraini

9

Elementtree'nin en son sürümü XPath'i oldukça iyi destekliyor. Bir XPath uzmanı değilim, uygulamanın dolu olup olmadığını kesin olarak söyleyemem, ancak Python'da çalışırken ihtiyacımın çoğunu karşıladı. Ayrıca lxml ve PyXML kullanıyorum ve standart bir modül olduğu için güzel buluyorum.

NOT: O zamandan beri lxml buldum ve benim için kesinlikle Python için en iyi XML lib. XPath'ı da güzel yapıyor (yine de belki tam bir uygulama değil).


7
ElementTree'nin XPath desteği şu anda en iyi düzeyde. Özellik seçicilerin eksikliği, varsayılan olmayan eksenler, alt dizin oluşturma yok, vb. Gibi büyük boşluk delikleri vardır. Sürüm 1.3 (alfa olarak) bu özelliklerin bazılarını ekler, ancak yine de utanç verici derecede kısmi bir uygulamadır.
James Brady

8

Sen basit kullanabilirsiniz soupparserdanlxml

Misal:

from lxml.html.soupparser import fromstring

tree = fromstring("<a>Find me!</a>")
print tree.xpath("//a/text()")

Soupparser kullanımı ne fark eder?
Padraic Cunningham

Bu sadece bir alternatif
Aminah Nuraini

7

XPATH'ın gücünün, herhangi bir noktada CSS kullanma yeteneğiyle birleştirilmesini istiyorsanız şunları kullanabilirsiniz parsel:

>>> from parsel import Selector
>>> sel = Selector(text=u"""<html>
        <body>
            <h1>Hello, Parsel!</h1>
            <ul>
                <li><a href="http://example.com">Link 1</a></li>
                <li><a href="http://scrapy.org">Link 2</a></li>
            </ul
        </body>
        </html>""")
>>>
>>> sel.css('h1::text').extract_first()
'Hello, Parsel!'
>>> sel.xpath('//h1/text()').extract_first()
'Hello, Parsel!'

"Bağlantı 1" ve "Bağlantı 2" yi almak istersem Xpath'ım nasıl görünmelidir?
weefwefwqg3

1
metni almak için, böyle bir şey olmalı//li/a/text()
eLRuLL


3

PyXML iyi çalışıyor.

Hangi platformu kullandığınızı söylemediniz, ancak Ubuntu'daysanız sudo apt-get install python-xml . Eminim diğer Linux dağıtımlarında da var.

Mac kullanıyorsanız, xpath zaten yüklüdür, ancak hemen erişilemez. PY_USE_XMLPLUSXml.xpath dosyasını içe aktarmadan önce ortamınızda ayarlayabilir veya Python yolu yapabilirsiniz:

if sys.platform.startswith('darwin'):
    os.environ['PY_USE_XMLPLUS'] = '1'

En kötü durumda, bunu kendiniz oluşturmanız gerekebilir. Bu paket artık korunmuyor, ancak yine de iyi bir yapı oluşturuyor ve modern 2.x Pythons ile çalışıyor. Temel dokümanlar burada .


0

Html için ihtiyacınız olacak :

import lxml.html as html
root  = html.fromstring(string)
root.xpath('//meta')
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.