[Python] BeautifulSoup 과 HTML 인코딩에 관한 고찰 Develop Tip

얼마전 필요에 따라 BeautifulSoup을 이용하여 HTML 파싱하여 
데이터를 추출하는 프로그램을 작성했는데,

HTML을 읽고 그 내용을 파싱하기 위하여 다음과 같이 시도했습니다.

    with open('1.html', 'r', encoding='utf-8') as ifp:
        hstr = ifp.read()
    soup = BeautifulSoup(hstr, self.parser)

말로 설명하면 1.html 이라는 HTML 파일을 UTF-8 로 열어 그것을 hstr 문자열에 넣고 BS로 파싱한다는 의미입니다.

그런데 문제는 이 HTML이 동일한 사이트라도 때때로 다른 인코딩으로 가져온다는 것이었습니다.
아마도 나라에 따라 해당 인코딩을 사용하게 한다던지 아니면 크롬 웹브라우저에서 Ctrl+U 로 HTML 소스를
읽어 저장하는 에디터 또는 OS 에 따라 해당 HTML 파일의 인코딩이 달라지는 것 같습니다.

아뭏든 일단 위의 코드가 때로는,

    with open('1.html', 'r', encoding='EUC-KR') as ifp:
        hstr = ifp.read()
    soup = BeautifulSoup(hstr, self.parser)

와 같이 해야 오류가 발생하지 않는 경우도 있었습니다.
이것을 해결하기 위해서 chardet 를 사용해도 됩니다.

import chardet

    with open('1.html', 'r', encoding='utf-8') as ifp:
        try:
            hstr = ifp.read()
        except UnicodeDecodeError:
            cd = chardet.detect(rawdata)
            # {'encoding': 'EUC-JP', 'confidence': 0.99}
            with open('1.html', 'r', encoding=cd['encoding']) as ifp:
                hstr = ifp.read()
        soup = BeautifulSoup(hstr, self.parser)

위의 코드는 일단 UTF-8 로 풀어 보고는 아니면 chardet 로 인코딩을 찾아
탐지한 인코딩으로 풀어보는 것입니다.
chardet 를 이용하면 대부분 잘 탐지를 하는데,
문제는 chardet 가 때로는 10여초 이상 탐지하는데 시간이 걸리는 경우도 있다는 것입니다.

암튼 이렇게 해결되려나.. 하다가 발견한 훨~씬 더 간단한 방법은..

    with open('1.html', 'rb') as ifp:
        soup = BeautifulSoup(ifp, self.parser)

이 두 줄로 간단히 해결되는 것이었습니다.

rb 바이너리 모드로 읽고 그 파일 객체를 BeautifulSoup에 인자로 넣어주면 
인코딩을 BS 안에서 자연스럽게 해결해 주는 군요.

하지만 20여 가지 이상을 테스트해 보니, chardet 만큼은 아니더라도 4초 이상 처리하는데
시간이 걸리는 것으로 보아 내부적으로 chardet 같은 것을 수행한다 판단되더군요.


어느 분께는 도움이 되셨기를 .. 



핑백

덧글

댓글 입력 영역

구글애드텍스트