파이썬에서 Xpath를 사용하는 방법?


224

Xpath를 지원하는 라이브러리는 무엇입니까? 완전한 구현이 있습니까? 도서관은 어떻게 사용됩니까? 웹 사이트는 어디에 있습니까?


4
나는이 질문에 대한 대답이 약간 오래되었다는이 음흉한 의심을 가지고 있습니다.
워렌 P

4
@ gringo-suave의 답변은 좋은 업데이트처럼 보입니다. stackoverflow.com/a/13504511/1450294
Michael Scheper 2016 년

Scrapy는 XPath 선택기를 제공합니다 .
cs95

@WarrenP가 말했듯이 여기에있는 대부분의 답변은 오래된 오래된 Python-2.x이며 실제로 오래되었습니다. 아마이 질문은 python-2.x
smci

답변:


129

libxml2 는 여러 가지 장점이 있습니다.

  1. 사양 준수
  2. 적극적인 개발과 지역 사회 참여
  3. 속도. 이것은 실제로 C 구현에 대한 파이썬 래퍼입니다.
  4. 편재. libxml2 라이브러리는 널리 사용되므로 잘 테스트되었습니다.

단점은 다음과 같습니다.

  1. 사양 준수 . 엄격합니다. 다른 라이브러리에서는 기본 네임 스페이스 처리와 같은 것이 더 쉽습니다.
  2. 네이티브 코드 사용 애플리케이션 배포 / 배포 방식에 따라 어려움이있을 수 있습니다. 이 고통을 덜어주는 RPM을 사용할 수 있습니다.
  3. 수동 리소스 처리. 아래 샘플에서 freeDoc () 및 xpathFreeContext ()에 대한 호출에 유의하십시오. 이것은 파이썬이 아닙니다.

간단한 경로 선택을하고 있다면 ElementTree (Python 2.5에 포함되어 있음)를 고수하십시오 . 전체 사양 준수 또는 원시 속도가 필요하고 원시 코드 배포에 대처할 수있는 경우 libxml2로 이동하십시오.

libxml2 XPath 사용 샘플


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 사용 샘플


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


8
osx에서 python 2.7.10을 사용하여 ElementTree를 다음과 같이 가져와야합니다.from xml.etree.ElementTree import ElementTree
Ben Page

C 래퍼이기 때문에 EC2 인스턴스 또는 AWS Linux의 Docker 이미지에서 컴파일하지 않으면 AWS Lambda에 배포하는 데 어려움이있을 수 있습니다.
CpILL

85

lxml이 패키지 지원은 XPATH. self :: axis에 문제가 있었지만 꽤 잘 작동하는 것 같습니다. Amara 도 있지만 개인적으로는 사용하지 않았습니다.


1
amara는 꽤 좋으며 xpath가 항상 필요한 것은 아닙니다.
gatoatigrado

lxml에서 XPath를 사용하는 방법에 대한 기본 세부 사항을 추가하십시오.
jpmc26

56

여기에 lxml 광고처럼 들립니다. ;) ElementTree는 std 라이브러리에 포함되어 있습니다. 2.6 이하에서 xpath는 매우 약하지만 2.7 이상에서는 크게 향상되었습니다 .

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을 사용하십시오. LXML은 libxml2 및 libxslt의 모든 기능을 사용하지만 해당 라이브러리에 고유 한 Python 바인딩보다 더 많은 "Pythonic"바인딩으로 랩핑합니다. 따라서 전체 XPath 1.0 구현을 얻습니다. Native ElemenTree는 XPath의 제한된 하위 집합을 지원하지만 필요에 따라 충분할 수도 있습니다.


29

또 다른 옵션은 py-dom-xpath 이며, minidom과 완벽하게 작동하며 순수한 Python이므로 appengine에서 작동합니다.

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

2
이미 minidom으로 작업하고 있다면 lxml 및 libxml2보다 쉽습니다. 아름답게 작동하고 더 많은 "Pythonic"입니다. contextfind기능을 사용하면 새 검색 컨텍스트와 같은 다른 XPath는 결과를 사용할 수 있습니다.
Ben

3
플러그인도 쓸 때 py-dom-xpath를 사용하고 있습니다. 순수한 파이썬이기 때문입니다. 그러나 더 이상 유지 관리되지 않는다고 생각 하고이 버그를 알고 있습니다 ( "이름이 'text'인 요소에 액세스 할 수 없습니다") : code.google.com/p/py-dom-xpath/issues/detail?id = 8
Jon Coombs

py-dom-xpath는 몇 년 전 2010 년에 모방 된 것으로 보입니다 . 최소한 귀하의 답변을 수정하십시오.
smci

14

당신이 사용할 수있는:

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

나는 PyXML에는 코드를하려고 할 때, 내가 가지고 ImportError: No module named ext에서from xml.dom.ext.reader import Sax2
Aminah Nuraini

9

elementtree 의 최신 버전 은 XPath를 꽤 잘 지원합니다. XPath 전문가가 아니기 때문에 구현이 가득 찼는 지 확실하게 말할 수는 없지만 Python에서 작업 할 때 대부분의 요구를 충족했습니다. 나는 또한 lxml과 PyXML을 사용했으며 표준 모듈이기 때문에 etree가 훌륭하다는 것을 알았습니다.

참고 : 나는 lxml을 찾았으며 파이썬을위한 최고의 XML 라이브러리입니다. XPath도 훌륭하게 수행합니다 (다시 완전한 구현은 아니지만).


7
ElementTree의 XPath 지원은 현재 최소 수준입니다. 속성 선택기 부족, 기본 축이 아닌 축, 자식 색인 없음 등과 같이 기능에 큰 차이가 있습니다. 버전 1.3 (알파)은 이러한 기능 중 일부를 추가하지만 여전히 부끄럽지 않은 부분 구현입니다.
James Brady

8

당신은 간단한 soupparser을 사용할 수 있습니다lxml

예:

from lxml.html.soupparser import fromstring

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

수프 파서를 사용하면 어떤 차이가 있습니까?
Padraic Cunningham

그것은 대안
일뿐입니다

7

언제라도 CSS를 사용할 수있는 기능과 XPATH의 기능을 결합하려면 다음을 사용할 수 있습니다 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!'

"링크 1"과 "링크 2"를 얻으려면 Xpath는 어떻게 보입니까?
weefwefwqg3

1
텍스트를 얻으려면 다음과 같아야합니다.//li/a/text()
eLRuLL


3

PyXML 이 잘 작동합니다.

어떤 플랫폼을 사용하고 있는지 말하지 않았지만 Ubuntu를 사용하는 경우와 함께 사용할 수 있습니다 sudo apt-get install python-xml. 다른 리눅스 배포판에도 마찬가지입니다.

Mac을 사용하는 경우 xpath가 이미 설치되어 있지만 즉시 액세스 할 수는 없습니다. PY_USE_XMLPLUSxml.xpath를 가져 오기 전에 환경에서 설정 하거나 Python 방식으로 수행 할 수 있습니다 .

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

최악의 경우 직접 빌드해야 할 수도 있습니다. 이 패키지는 더 이상 유지 관리되지 않지만 여전히 잘 빌드되고 최신 2.x Python에서 작동합니다. 기본 문서는 여기에 있습니다 .


0

html 에 필요한 경우 :

import lxml.html as html
root  = html.fromstring(string)
root.xpath('//meta')
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.