2010-01-02 4 views
4

HTMLParser 클래스를 파이썬에서 사용하는 경우 handle_* 함수 내에서 처리를 중단 할 수 있습니까? 처리 초기에는 필요한 모든 데이터를 얻었으므로 처리를 계속하는 것이 낭비처럼 보입니다. 아래에 문서에 대한 메타 설명을 추출하는 예제가 있습니다.Python에서 HTMLParser 처리를 중단하십시오

from HTMLParser import HTMLParser 

class MyParser(HTMLParser): 

    def handle_start(self, tag, attrs): 
     in_meta = False 
     if tag == 'meta': 
      for attr in attrs: 
       if attr[0].lower() == 'name' and attr[1].lower() == 'description': 
        in_meta = True 
       if attr[0].lower() == 'content': 
        print(attr[1]) 
        # Would like to tell the parser to stop now, 
        # since I have all the data that I need 
+2

파서가 아닌 HTMLParser를 상속 받아야합니까? –

+1

오, HTML을 파싱하기 위해 BeautifulSoup을 사용하는 것이 좋습니다. 사용하기가 훨씬 쉽습니다. –

+0

나는 이것이 오타 일 뿐이라는 결론에 도달하기 쉽다고 생각합니다. 왜냐하면이 코드가 아니라면이 코드는 작동하지 않기 때문입니다. – shylent

답변

9

예외를 발생시키고 .feed() 호출을 try 블록으로 래핑 할 수 있습니다. 당신이 결정할 때

당신은 또한 당신이 수행되어, self.reset() 호출 할 수 있습니다 (I 실제로 그것을 시도했지만 documentation에 따라 ".. 인스턴스를 재설정 모든 처리되지 않은 데이터를 잃는다"하지 않은, - 이것은 당신이 필요 정확하게).

+3

예외는 좋은 생각처럼 들리지 않는다 - 예외는 예외적 인 조건에서만 사용되어야하며,이 경우 제어 흐름 도구로 사용하도록 제안하면됩니다. '리셋'메소드에 관해서도 나는 그것을 고려해 보았으나, 여기에 정말로 관련이 있는지를 알 수는 없다. –

+5

: "예외적 인 예외 조건들"- 파이썬에서는 그렇지 않다. StopIteration은 iterator가 "반복적으로"실행되지 않을 때마다 발생합니다. 그것은 "예외적 인 조건"이 아닙니다. 지금입니까? 사실 그것은 질문자가 처리하기를 원하는 상태, 즉 "지금 당장 깨는"상태와 분명히 비슷합니다. – shylent

+2

@shylent : StopIteration에 대해서는 true이지만 수동으로 처리하는 경우는 거의 없지만 사용자가 거의 직접 본 적이 없도록 포장됩니다. 그럼에도 불구하고, 당신은 좋은 지적을하고 있습니다. –

1

pyparsing의 scanString 메서드를 사용하면 실제로 입력 문자열을 얼마나 멀리 통과하는지 더 많이 제어 할 수 있습니다. 귀하의 예에서는 <meta> 태그와 일치하는 표현식을 작성하고 name="description" 태그 만 일치하도록 구문 분석 조치를 추가합니다. 이 코드는 사용자가 변수 htmlsrc에 페이지의 HTML을 읽고 있다고 가정

class MyParser(HTMLParser): 

    boolean_flag = False 

    def handle_starttag(self, tag, attrs): 
     # for example: 
     self.boolean_flag = (tag == "sometag" and ("id", "someid") in attrs) 

    def handle_endtag(self, tag): 
     pass 

    def handle_data(self, data): 
     if self.boolean_flag: 
      raise DataParsedException(data) 


class DataParsedException(Exception): 
    def __init__(self, data): 
     self.data = data 

사용법 :

try: 
    parser.feed(html.decode()) 
except DataParsedException as dataParsed: 
    vars.append(dataParsed.data) 

그것은 않습니다

from pyparsing import makeHTMLTags, withAttribute 

# makeHTMLTags creates both open and closing tags, only care about the open tag 
metaTag = makeHTMLTags("meta")[0] 
metaTag.setParseAction(withAttribute(name="description")) 

try: 
    # scanString is a generator that returns each match as it is found 
    # in the input 
    tokens,startloc,endloc = metaTag.scanString(htmlsrc).next() 

    # attributes can be accessed like object attributes if they are 
    # valid Python names 
    print tokens.content 

    # if the attribute name clashes with a Python keyword, or is 
    # otherwise unsuitable as an identifier, use dict-like access instead 
    print tokens["content"] 

except StopIteration: 
    print "no matching meta tag found" 
+2

답변 해 주셔서 감사합니다. 나는 이것이 잘 작동하는 것을 확신하고 pyparsing에 대해 약간의 소개를 해 주셔서 감사합니다. 내가 할 수 있으면 나는 둘 다 맞을 것입니다. –

0

는 @ shylent의 대답에 확장, 여기 내 솔루션입니다 작업.

관련 문제