2011-12-25 3 views
5

야생 웹에서 임의의 문서 다운로드를 구문 분석하려고하는데 예, 해당 내용을 제어 할 수 없습니다.Beautiful Soup가 UnicodeEncodeError를 "ordinal in range (128)"로 올립니다.

Beautiful Soup won't choke if you give it bad markup... 때문에 나는 때로는 문서의 부분이 잘못된 경우 왜 나에게 그 시골뜨기 업을 제공 않습니다 궁금와 관계없이이의는 문서의 다음 읽을 수있는 부분에 다시 만들 수있는 방법이 있는지 여부 오류.

오류가 3 일 발생한 라인 :

from BeautifulSoup import BeautifulSoup as doc_parser 
reader = open(options.input_file, "rb") 
doc = doc_parser(reader) 

CLI 전체 출력은 :

Traceback (most recent call last): 
    File "./grablinks", line 101, in <module> 
    sys.exit(main()) 
    File "./grablinks", line 88, in main 
    links = grab_links(options) 
    File "./grablinks", line 36, in grab_links 
    doc = doc_parser(reader) 
    File "/usr/local/lib/python2.7/dist-packages/BeautifulSoup.py", line 1519, in __init__ 
    BeautifulStoneSoup.__init__(self, *args, **kwargs) 
    File "/usr/local/lib/python2.7/dist-packages/BeautifulSoup.py", line 1144, in __init__ 
    self._feed(isHTML=isHTML) 
    File "/usr/local/lib/python2.7/dist-packages/BeautifulSoup.py", line 1186, in _feed 
    SGMLParser.feed(self, markup) 
    File "/usr/lib/python2.7/sgmllib.py", line 104, in feed 
    self.goahead(0) 
    File "/usr/lib/python2.7/sgmllib.py", line 143, in goahead 
     k = self.parse_endtag(i) 
    File "/usr/lib/python2.7/sgmllib.py", line 320, in parse_endtag 
    self.finish_endtag(tag) 
    File "/usr/lib/python2.7/sgmllib.py", line 358, in finish_endtag 
    method = getattr(self, 'end_' + tag) 
UnicodeEncodeError: 'ascii' codec can't encode characters in position 15-16: ordinal not in range(128) 
+0

BeautifulSoup에 어떤 입력을하고 계십니까? 오류 메시지에 따르면 ASCII가 아닌 일부 데이터 (예 : 비 라틴 문자 포함)를 파싱하는 중일 수 있습니다. –

+0

나는 파싱 데이터가 야생 웹에서 왔으며, 그 부분은 확실히 아스키가 아니다. –

답변

2

예 : 비 ASCII 이름 (<café>)을 가진 요소가있는 경우 초크가 발생합니다. XML의 경우에도 '나쁜 마크 업'이 아닙니다.

BeautifulSoup이 사용하고있는 버그는 sgmllib입니다 : 태그와 이름이 같은 맞춤형 메소드를 찾으려고 시도하지만 Python 2 메소드 이름은 바이트 문자열입니다 심지어 이 아닌 ASCII가 아닌 문자가 포함 된 메소드에 대한을 보면 심지어 존재하지도 않습니다.

줄 259와 371을 except AttributeError:에서 except AttributeError, UnicodeError:으로 변경하여 sgmllib에 수정 사항을 해킹 할 수 있지만 그다지 좋은 해결책은 아닙니다. 나머지 메소드를 오버라이드하는 것은 쉽지 않습니다.

구문 분석하려고하는 것은 무엇입니까? BeautifulStoneSoup은 언제나 의문의 여지가있었습니다. XML은 HTML이하는 엄청난 파서 해킹이 없었기 때문에 일반적으로 XML은 XML이 아닙니다. 따라서 일반적으로 일반 XML 파서 (예 : 표준 DOM 또는 etree 사용)를 사용해야합니다. 일반적인 HTML 구문 분석을 위해서는 요즘 더 좋은 옵션 인 html5lib이 좋습니다.

+0

구문 분석기가 ASCII가 아닌 문자 만 지원하는 regexp를 사용하여 _start_ 태그와 일치하려고하면 오류가 실제로 먼저 시작되기 때문에 사용자가 제안한 해결 방법은 전혀 작동하지 않습니다. 즉, 유효한 시작 태그는 'UnicodeEncodeError'가 발생하기 전에 건너 뜁니다. – ekhumoro

+0

@bobince, 나는 당신의 제안에 따라 * _endtag와 * _startag 메소드를 위해'UnicodeError','UnicodeEncodeError'와'UnicodeDecodeError' (https://gist.github.com/1520499#L331 참조)를 추가했습니다. 예상 한 결과, 이진 파트를 건너 뛰고 관련 청크 만 추출하면됩니다. 감사! –

0

파이썬 버전의 입력 이전에 비 ASCII 문자가있을 경우 이런 Python 3.0

str(...)을 char 값> 128 (ANSII & 유니 코드) 인 문자가 포함 된 문자열에 사용하려는 경우이 예외는 r입니다. aised.

getattr은 유니 코드 문자열에 str을 사용하려고하기 때문에 오류가 발생할 수 있습니다. 3.0 이전의 Python 버전에서는 유니 코드를 포함 할 수 없으므로 안전하게 수행 할 수 있다고 생각합니다.

유니 코드 문자를 HTML에서 확인하십시오. 이것을 대체하거나 인코딩하려고 시도하지만 여전히 작동하지 않는다면 우리에게 알려주십시오.