2010-07-18 2 views
23

python HTMLParser 라이브러리를 사용하여 HTML 페이지에서 값을 가져 오려고합니다. 내가의 개최 얻을하려는 값이 HTML 요소 내에 :파이썬 HTMLParser 라이브러리를 사용하여 특정 div 태그에서 데이터를 추출하려면 어떻게해야합니까?

... 
<div id="remository">20</div> 
... 

이 내 HTMLParser 클래스는 지금까지입니다 :

class LinksParser(HTMLParser.HTMLParser): 
    def __init__(self): 
    HTMLParser.HTMLParser.__init__(self) 
    self.seen = {} 

    def handle_starttag(self, tag, attributes): 
    if tag != 'div': return 
    for name, value in attributes: 
    if name == 'id' and value == 'remository': 
     #print value 
     return 

    def handle_data(self, data): 
    print data 


p = LinksParser() 
f = urllib.urlopen("http://domain.com/somepage.html") 
html = f.read() 
p.feed(html) 
p.close() 

은 누군가가 올바른 방향으로 날 포인트? 나는 클래스 기능 (20)

+1

당신이 HTML 구문 분석을 많이 수행하는 경우, 시도 [아름다운 수프] (http://www.crummy.com/software/BeautifulSoup/). – zvone

+3

그 라이브러리는 파이썬 표준 라이브러리로 포함되어 있습니까? 나는 HTMLParser를 고수하기로 결심했다. – Martin

+0

@zvone 왜 html 구문 분석을 위해 BeautifulSoup이 더 나은가요? 여전히 권장 모듈입니까? 감사. –

답변

44
class LinksParser(HTMLParser.HTMLParser): 
    def __init__(self): 
    HTMLParser.HTMLParser.__init__(self) 
    self.recording = 0 
    self.data = [] 

    def handle_starttag(self, tag, attributes): 
    if tag != 'div': 
     return 
    if self.recording: 
     self.recording += 1 
     return 
    for name, value in attributes: 
     if name == 'id' and value == 'remository': 
     break 
    else: 
     return 
    self.recording = 1 

    def handle_endtag(self, tag): 
    if tag == 'div' and self.recording: 
     self.recording -= 1 

    def handle_data(self, data): 
    if self.recording: 
     self.data.append(data) 

self.recording 카운트 값에게 "트리거"하나에서 시작 중첩 div 태그의 수를 싶어. 트리거 태그를 기반으로하는 하위 트리에있을 때 데이터는 self.data에 누적됩니다.

구문 분석의 끝 부분에있는 데이터는 self.data (트리거 목록이없는 경우 문자열 목록)에 남습니다. 클래스 외부의 코드는 구문 분석이 끝날 때 인스턴스에서 직접 목록에 액세스 할 수 있으며, 목표가 정확히 무엇인지에 따라 목적에 맞는 적절한 접근 자 메서드를 추가 할 수 있습니다.

클래스를 쉽게 할 수있는 상기 코드 'div', 'id' 볼 상수 리터럴 스트링 대신에 사용하여 좀 더 일반적인 제조 및 'remository' 예 인수로부터 __init__ 설정 self.tag, self.attnameself.attvalue을 속성 여기에 전달했습니다. 핵심 포인트가 불분명 해지는 것을 방지하기 위해 위의 코드에서 싼 일반화 단계를 피했습니다 (중첩 된 태그 수를 추적하고 기록 상태가 활성 상태 일 때 목록에 데이터를 누적).

HTMLParser.HTMLParser.__init__(self) 3 호선에서

+1

감사합니다 알렉스, 그 코드는 완벽하게 작동합니다 ("if tag == div and self.recording :"- div는 문자열이어야 함). 값을 반환하는 클래스의 의미는 실제로 클래스 내에서 필요한 값을 반환하는 함수 인 것으로 설명했습니다. 또는 '데이터'변수에 쉽게 액세스 할 수 있습니다. 내가 거기에 있던 사전은 가능한 해결책을 테스트하는 저의 남을 추방이었습니다 :) 당신의 도움에 감사드립니다! – Martin

+1

중첩 된'div's의 수는 + html 파싱에 처음으로 접근하는 사람에게는 그리 명확하지 않습니다. –

+0

@Martin, 환영합니다. +1주의를 산만하게합니다. 미래의 독자들에게 더 많은 유용성을주기 위해 수정 ('div'를 인용하고 그 dict & comment를 수정)합니다. –

4

리틀 보정이

HTMLParser.__init__(self)

이 (가)

import urllib2 

from HTMLParser import HTMLParser 

class MyHTMLParser(HTMLParser): 

    def __init__(self): 
    HTMLParser.__init__(self) 
    self.recording = 0 
    self.data = [] 
    def handle_starttag(self, tag, attrs): 
    if tag == 'required_tag': 
     for name, value in attrs: 
     if name == 'somename' and value == 'somevale': 
      print name, value 
      print "Encountered the beginning of a %s tag" % tag 
      self.recording = 1 


    def handle_endtag(self, tag): 
    if tag == 'required_tag': 
     self.recording -=1 
     print "Encountered the end of a %s tag" % tag 

    def handle_data(self, data): 
    if self.recording: 
     self.data.append(data) 

p = MyHTMLParser() 
f = urllib2.urlopen('http://www.someurl.com') 
html = f.read() 
p.feed(html) 
print p.data 
p.close() 

`

불구하고 나를 위해 일한 다음이어야한다
+3

실제로 HTMLParser를 호출 할 수있게 해주는'from HTMLParser import HTMLParser'를 지정했기 때문에 그렇게 할 수 있습니다. 둘 다 같은 이름을 지니고는 있지만 두 개의 다른 실체라는 것은 불행한 일입니다. 'HTMLParser에서 HTMLParser를 파서로 가져 오기 '와 같은 작업을 수행 한 다음'class MyHTMLParser (parser)'를 사용하면됩니다. –

22

시도해 보셨습니까 BeautifulSoup?

from bs4 import BeautifulSoup 
soup = BeautifulSoup('<div id="remository">20</div>') 
tag=soup.div 
print(tag.string) 

그러면 출력이 20이됩니다.

0

이 완벽하게 작동합니다 :

print (soup.find('the tag').text)