BeautifulSoup 를 이용한 html 파싱시 주의해야 할 점


군입대 전에 잠시 할 수 있는 아르바이트를 구하였습니다. 주된 업무는 이미 제공되고 있는 웹컨텐츠를 로컬에서 파일로 저장하여 고객사에 납품하는 일입니다. 하루종일 웹페이지를 열고, 크롬의 개발자 툴로 원하는 부분을 긁어와서 파일로 저장하고, 고객사에서 지정된 형식대로 폴더 형식과 여러 스크립트를포함해야 되는 단순하지만 반복적이고 귀찮은 작업이었습니다. 기존에 계시던 개발자분들은 이걸 할 수 있는 시간상 여유가 없으셔서 저를 알바로 뽑으셨던거죠. 처음 한달간은 하루종일 손가락을 써가며 웹에서 컨텐츠를 긁어오다가 문득 든 생각이 '이걸 자동화를 할 수는 없을까' 라는 생각이 들었습니다.

Selenium, BeautifulSoup 를 이용한 자동화 프로그램이죠. 미리 지정된 형식의 html 파일을 로컬에 하나 저장합니다. 그리고 Selenium 에서 웹컨텐츠를 순차적으로 로딩하여 BeautifulSoup 로 넘겨주고 BeautifulSoup 는 미리 로컬에 저장된 템플릿에 웹에서 긁어온 컨텐츠의 일부 클래스를 탬플릿에 넣어주고 로컬에 폴더형식을 맞춰서 저장해주는 방식이었습니다.

일단 Selenium, BeautifulSoup 의 API 를 참조하여 반나절만에 크롤링 프로그램을 쉽게 만들 수 있었습니다. 제가 한달걸려 했던 작업을 프로그램 제작 기간까지 단 3일만에 끝낼 수 있도록 말이죠. 저를 고된 손가락 운동에서 해결될 수 있도록 해준 BeautifulSoup 개발자분들에게 진심으로 감사한 순간이었습니다. 그런데 Beautiful Soup 문서 에서도 주의가 필요한 부분을 설명하지 않고 지나가는 부분이 있어서 이 문서를 작성하게 되었습니다.

BeautifulSoup 가 문서를 파싱해 올때에는   & < > " 등의 특수문자를 전부 Unicode 문자열로 바꾸어 버립니다. 아래 코드입니다.

아래는 실행결과입니다.
보시는바와 같이 html 문서의 특수코드를 유니코드로 바꿔버립니다. BeautifulSoup 의 문서를 참조하더라도 처음부터 이걸 바꾸지 않는 방법을 찾을 수 없었습니다.
문서를 계속 보던 중 찾게 된 방법은, Output Formatter를 설정하면 빈칸 등이 html 특수코드로 다시 바뀌는걸 확인하실 수 있습니다.

실행결과에는 정상적으로     가 들어간 것을 보실 수 있습니다.

prettify() 메소드를 사용하면 위의 결과와 같이 태그가 열리고 닫힐 때마다 새로운 줄에 들여쓰기가 포함되게 됩니다. 공식 문서에서도 설명되지 않은 문제가 될 수 있는 부분이 바로 여기서 발생됩니다. 아래 소스코드를 보시죠.

결과를 보실까요.
보시다시피 매 태그마다 새로운 줄로 시작됩니다. 겉보기에는 문제가 없을 듯 하지만, 이걸 html로 저장하고 브라우저에서 열면 어떤 결과가 나올까요?
제가 생각했던 결과는 "한줄로 나와야되는문서입니다. 그런데 빈칸이 들어가죠." 입니다. 과연 그럴까요? 이걸 html문서로 저장해봅시다.
이걸 브라우저에서 열었을때 실제 결과입니다.
빈칸이 하나 더 들어간걸 보실 수 있습니다. 보통 html 문서에서 글자의 형태등을 세부적으로 지정할때 span 태그를 이용하는 경우가 많은데 BeautifulSoup 의 prettify 메소드를 이용할 때 의도치않은 이런 문제가 발생합니다.

네, 덕분에 저는 내일가서 제가 만든 프로그램의 소스코드를 수정하고 다시 모든 웹사이트를 크롤링 해와야 할 것 같습니다(...) QA팀에서 검수가 이미 들어갔는데 아마 지금쯤 빈칸 때문에 검수요청이 잔뜩 들어와있을것 같습니다.

해결방법을 설명해드리겠습니다.
마지막줄에 파일로 저장하는 부분을 보시면 encode 와 decode 과정을 거칩니다. 아무리 문서를 찾아봐도 String을 출력할때 바로 formatter 형식을 지정할 수 있는 방법은 없었습니다. 그래서 유니코드 바이트로 인코딩한 후에 다시 문자열로 디코딩을 하여 파일로 저장하는 방법을 택하였습니다. 이제 브라우저에서 파일을 열어봅시다.
네, 드디어 빈칸이 없어졌습니다!
저는 내일 출근하여 지금까지 찾은 방법대로 자동화 프로그램을 개선하고, 다시 전체 문서를 크롤링해와야 겠습니다. 덧붙여서 여태까지 만들어둔 자동화 프로그램의 문서화도 완료해야 되겠구요.

정말 BeautifulSoup 와 Selenium 덕분에 몇날 며칠 걸릴 일들을 조금의 검수로 단 몇시간만에 끝낼 수 있었습니다. 또 직접 손으로 작업했을 시 생길 수 있는 오류도 원천 방지할 수 있고요. 시간이 난다면 Selenium 과 BeautifulSoup 로 크롤링을 해오는 기본적인 방법들을 한번 올리겠습니다.

댓글

  1. 저 궁금한게 있는데 그냥 https://www.crummy.com/software/BeautifulSoup/bs4/doc/#non-pretty-printing 여기처럼 첨부터 utf-8 로 인코딩 하면 되는거 아닌가요?

    답글삭제
    답글
    1. 그러게요.. 그냥 출력하면 되는걸 왜 저렇게 했지..
      저때 당시에 파이썬을 처음 쓰느라 그냥 되는대로 만든거 같습니다;

      삭제

댓글 쓰기