R Crawler 3 부록

한글 인코딩 문제 해결 방법

Dr.Kevin 1/27/2018

R Crawler 3 User Agent 설정하기 포스팅에서 아래와 같이 웹데이터를 수집할 때 Windows 사용자는 에러가 발생해서 당황스러울 겁니다. Mac 사용자는 이 포스팅을 확인할 필요가 없습니다!

# 필요 패키지를 불러옵니다.
library(httr)
library(rvest)
library(dplyr)
# User-Agent를 지정합니다.
ua <- user_agent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36")
# url을 지정합니다.
url <- "http://land.naver.com/article/articleList.nhn?rletTypeCd=A01&tradeTypeCd=A1&hscpTypeCd=A01%3AA03%3AA04&cortarNo=1156011000&articleOrderCode=&siteOrderCode=&cpId=&mapX=126.9310828&mapY=37.5213899&mapLevel=10&minPrc=&maxPrc=&minWrrnt=&maxWrrnt=&minLease=&maxLease=&minSpc=&maxSpc=&subDist=&mviDate=&hsehCnt=&rltrId=&mnex=&mHscpNo=&mPtpRange=&mnexOrder=&location=&ptpNo=&bssYm=&schlCd=&cmplYn="

# ua를 추가해서 html request 합니다.
resp <- GET(url, ua)

# 응답 상태코드를 확인합니다.
status_code(resp)
# 아파트 매물 리스트를 수집합니다.
aptList <- read_html(resp) %>% 
  html_node(css = "table") %>% 
  html_table(fill = TRUE)

마지막 스크립트에서 html_table(fill = TRUE)를 제외하고 윗 두 줄만 실행했을 때는 별 문제 없이 잘 돌아갑니다만, 어떤 이유에서인지 마지막 줄을 포함시켜서 실행하면 안 됩니다. 이 문제는 결과적으로는 인코딩 때문에 발생합니다.

WindowsCP949 인코딩 방식을 따릅니다. 그리고 예제 사이트는 UTF-8 방식으로 텍스트를 처리하는데요. 이 문제를 회피하는 방식으로 다음과 같은 꼼수(!)를 알려드리겠습니다.

다음 명령을 실행하여 지금 사용하고 있는 컴퓨터에서 R의 인코딩 방식을 확인해보겠습니다.

# 인코딩 방식을 확인합니다.
localeToCharset()

저는 MacOS를 사용하고 있기 때문에 UTF-8으로 출력되지만, Windows를 사용하는 경우 CP949로 출력될 것입니다. 이를 해결하기 위해 로케일을 변경해주어야 합니다.

나라마다 서로 다른 문화를 갖고 있다 보니, 시간을 표시하는 방법이라든가 숫자를 표시하는 방법 등에서 상당한 차이를 보입니다. 그래서 OS는 각 언어마다 서로 다른 로케일을 제공하고 있으며, 로케일을 변경하면 문자의 경우 인코딩 방식이 함께 변경되는 것입니다.

이번 포스팅에서는 아래와 같이 C로 변경해보겠습니다. C는 컴퓨터 언어인 C의 기본 로케일이며, 북미에서 사용하는 로케일로 설정됩니다[1].

# 로케일을 변경합니다.
Sys.setlocale(category = "LC_All", locale = "C")

# 인코딩 방식을 재확인합니다.
localeToCharset()

인코딩 방식이 ASCII로 바뀌었습니다. 이 상태에서 문제가 되었던 스크립트를 실행해보면 이제 정상적으로 실행될 것입니다.

# 아파트 매물 리스트를 수집합니다.
aptList <- read_html(resp) %>% 
  html_node(css = "table") %>% 
  html_table(fill = TRUE)

하지만 여전히 문제가 남아 있습니다. RStudio의 오른쪽 상단에 있는 Environment 창에서 방금 생성한 aptList 객체를 클릭해서 보면 한글 부분이 모두 깨져서 보일 것입니다. 왜 이런 일이 발생할까요? 저는 인코딩 방식이 충돌해서 난 문제라고 생각하고 있습니다.

그럼 첫 번째 컬럼의 인코딩 방식을 확인해보겠습니다.

# 첫 번째 컬럼의 인코딩 방식을 확인합니다.
Encoding(aptList[[1]])

모두 UTF-8으로 출력됩니다. 정리해 보면, 예제 사이트는 UTF-8으로 텍스트 데이터를 처리하는데 여러분이 사용 중인 WindowsCP949 방식을 사용하고 있으므로 데이터 프레임을 만들 때 문제가 되었던 것입니다. 이를 회피하기 위해 로케일을 잠시 변경해서 aptList를 생성할 수 있었지만, 다시 인코딩 문제로 한글이 제대로 보이지 않는 것입니다.

이걸 회피하는 방법은 다시 로케일을 원래대로 바꿔주면 됩니다.

# 로케일을 원래대로 변경합니다.
# locale 인자 없이 category 인자만 할당해도 제대로 실행됩니다.
Sys.setlocale(category = "LC_All", locale = "Korean")

# 인코딩 방식을 재확인합니다.
localeToCharset()

이 상태에서 aptList를 클릭해서 육안으로 확인해보세요. 이제 제대로 보이죠? 위와 같은 꼼수로 문제를 해결할 수 있었습니다.

[1] 자세한 사항은 locales 설명서를 참고하세요

Written on January 27, 2018