2011-03-05 6 views
0

파이썬에서 html 파일을 구문 분석하고 목록에 내용을 저장해야합니다. 예 : 지금 여기파이썬에서 "<"문자로 인터럽트하는 (파싱하는) 파일의 일부를 읽는 방법은 무엇입니까?

def getTexte(fp,compte=0): #returns the text before a html tag 
    txt="" 
    pos=fp.tell() #stock the curr position for later use 
    tmppos=fp.tell() #same here 
    for car in fp.read(): 
     if car=="<": #if we encounter the start of a html tag 
      fp.seek(tmppos) #we get back to juste before the html tag 
      break # and we leave this damn for 
     txt=txt+car #we concatenate each car in the string 
     tmppos=fp.tell() #and stock the pos for later use 
    if compte==0: 
     fp.seek(pos) 
    if txt!="": 
     return txt 

샘플 내가 얻을 출력됩니다 : 여기 ['<html>', '<head>', '<meta name="robots" content="noindex">']

내가 buggish 기능에 지금 무엇을 가지고

['<p>', 'Blablabla', 'lablabla', 'ablabla', 'blabla', 'labla', 'abla', 'bla', 'la', 'a', '</p>'] 

그리고 난 이유를 이해할 수 없다 . 어쩌면 너무 피곤했다.

+1

왜 BeautifulSoup와 같은 파서를 사용하지 않습니까? –

+2

(1) HTML 파싱은 잘못된, 완전히 가짜 인 "마크 업"을 처리 할 때까지 해결 된 문제입니다. (2) 당신은 지금 토큰 화하고 있습니다. 파싱에는 훨씬 더 많은 것이 있습니다. (3) 렉서를 손으로 쓰는 것은 쉽지 않습니다. 손으로 전체 구문 분석기를 작성하는 것은 대부분의 구문 분석 작업에 비실용적입니다. (4) 손으로 직접 해보려한다면 가장 좋은 방법은 FSM입니다.regex (손으로 non-trivial FSM을 작성하는 것은 다시 매우 추악하고 불필요합니다). – delnan

+0

아마 당신이 질문에 추가 할 수있는 가장 유용한 것은 당신이 해결하려고하는 진짜 문제에 대한 설명입니다. (예를 들어 왜 그 요소를 평평한 목록에 넣고 싶은지 명확하지 않거나, 요소로 묶인 텍스트를 어떻게 처리 할 것인지 등등) –

답변

4

다른 사람들의 의견에 따르면 일련의 문자로 입력을 반복하여 HTML 파서를 작성하려고하지는 않습니다. 코드 조각의 tell()read() 메서드에 대한 참조는 높은 수준 (버퍼로 문자열로 읽은 문서)을 생각하는 것보다 열린 파일을 통해 걷는 관점에서 생각하는 것이 좋습니다.

많은 종류의 도구가 이미 작성되어 있으며, 자유롭게 사용할 수 있고, 광범위하게 테스트를 거치며, 잘 유지 관리되고 광범위한 평가를 받고 있습니다. 이것들 중에서 가장 인기있는 것은 "BeautifulSoup"라고 불리는 것입니다. 이것은 "현실 세계"에서 발견되는 HTML의 견고 함과 내구성에 대해 유명합니다. BeautifulSoup의 목표는 대충 말하면 브라우저가 합리적으로 표시 할 수있는 HTML을 파싱하는 것입니다. 따라서 HTML의 부적절하게 중첩 된 태그, 누락 된 닫는 태그가있는 컨테이너, 비표준 태그 및 비표준 및 부적절한 속성 및 속성 = 값 쌍을 포함한 태그 등 매우 다양한 매우 일반적인 오류를 처리 할 수 ​​있습니다. 당신은 여기에 라인의 몇 가지를 설명 BeautifulSoup로에 대한 참조를 볼 수 ...

#!/bin/env python 

import urllib2 
from BeautifulSoup import BeautifulSoup 

def get_page(url): 
    fetcher = urllib2.urlopen(url) 
    results = fetcher.read() 
    fetcher.close() 
    return results 

def find_tags(data): 
    results = list() 
    parser = BeautifulSoup(data) 
    results.extend(parser.findAll()) 
    return results 

if __name__ == '__main__': 
    import sys, time 

    for url in sys.argv[1:]: 
     html=get_page(url) 
     for n, each in enumerate([str(x) for x in find_tags(html)]): 
      print n, each, '\n\n\n' 

:

여기 BeautifulSoup로를 사용하여 일부 파이썬 코드의 매우 간단한 예입니다. 나머지는 HTML을 가져 와서 결과를 인쇄합니다.

이 결과는 각 HTML 컨테이너의 가장 바깥 쪽부터 아래쪽까지 및 그 구성 요소를 통해 깊이있는 순회를 나타냅니다. 코드에서이 트리를 탐색하여 리프에있을 때를 결정한 다음 텍스트/내용 또는 태그/코드를 캡처 할 때 어떤 방식 으로든 캡처 할 수 있습니다. 귀하의 요구 사항을보다 정확하게 충족시킬 수있는 자세한 내용은 BeautifulSoup: Documentation을 읽어보십시오.

+0

왜''results = fetcher.read()' '가 아닌가? '** get_page (url) ** 및 **'find = parser.findAll()''** find_tags (data) **에서? – eyquem

+0

@eyquem :이 코드는 실제로 회사에서 실행되는 작은 내부 유틸리티에서 붙여 넣었습니다. (쿼리를 위해 다른 편리한 인터페이스를 노출시키지 않는 내부 모니터링 애플리케이션에서 대시 보드 페이지를 긁어 낸다.) 여기에있는 코드는 의도적으로 거의 최소로 단순화되었지만, 읽기 쉽고 코드에 예외 처리 및 기타 성가신 세부 사항이 있기 때문에 약간 장황하다. 내용의 slurping에 대한 .read()에 대한 .readlines() 선호는 개인적인 단점입니다. 그것은 내가 익숙한 (하지만 그것을 바꾸는) 것이다. .extend()를 사용하여 BS obj가 아닌 목록에 결과를 적용합니다. –

0

구문 분석 된 html의 출력을 사용하려면 Beautiful Soup을 살펴보십시오. 유효하지 않은 마크 업을 먹여도 HTML (및 XML)이 올바르게 파싱되는지 확인하는 데 많은 시간이 걸린다.

파서를 만들어야합니까? 아니면 그냥 파서의 출력을 사용해야합니까? 이것은 StackOverflow에서 얻는 도움의 종류를 결정합니다. 많은 경우, 제안 된 솔루션 및 문제점과 함께 사용자의 의도 (요구 사항)를 알려줌으로써 사용자는 요구 사항에 더 적합한 대체 솔루션을 지적하게됩니다. 생각할 거리.

관련 문제