Node js request 한글 깨짐 - Node js request hangeul kkaejim

content-type에 charset이 매우 이상하다 보시다 시피 위 코드에 charset이 utf로 인코딩이 되어지지 않았기 때문이다. 그렇다면 위 코드의 body를 출력을 해보면?

매우매우 깨져서 나온다.

(만약에 웹페이지에서 meta charset이 utf8로 됬다면 정상적으로 출력이 된다)

그렇다면 utf가 아닐때 인코딩을 해주면 된다.

나는 npm에서 제공되는 모듈중 하나인 

iconv을 사용할 것이다.

npm install iconv

모듈을 설치를 해주자.

var Iconv = require('iconv').Iconv;

cs

iconv모듈을 물러와주자 

var iconv = new Iconv('EUC-KR', 'UTF-8')

var searchResultBin = new Buffer(body, 'binary');

var html = iconv.convert(searchResultBin).toString();

cs

불러온 모듈을 이용하여 객체를 생성한다 해당 객체는 EUC-KR을 UTF-8로 바꿔주는 객체이다

그리고 인코딩 할 스트링을 바이너리로 바꿔준다. 바이너리로 바꿔야 손실이 없다.

바이너리 데이터를 iconv.convert에 넣어주고 string으로 바꿔주면 된다.

참고로 이건 cheerio로 load시킨후 text만 추출해서 출력시킨 결과이다.

정상적으로 한글이 인코딩이 된다.

그리고 이들을 종합하여 utf8인 경우와 아닌경우 모두 해결이 되는 방법으로 약간 수정을 해보았다.

(물론 급하게 짠거라 코드가 좀 지저분하지만...._ㅋㅋㅋㅋㅋ)

var request = require('request');

var cheerio = require('cheerio');

var Iconv = require('iconv').Iconv;

page_req(url).then(function(html){

var page_req = function(url){

    return new Promise(function(resolve, reject){

                'content-type' :'text/html;charset=utf-8'

            headers:{'User-Agent':"Mozilla/5.0"}

        }, function(err, res, body){

            var contentType =  res.headers['content-type'].toLowerCase();

            if(contentType.indexOf('utf')>-1){

                        'content-type' :'text/html;charset=utf-8'

                    headers:{'User-Agent':"Mozilla/5.0"}

                },function(err, ress, html){

                    console.log(ress.headers)

                var iconv = new Iconv('EUC-KR', 'UTF-8')

                var searchResultBin = new Buffer(body, 'binary');

                var html = iconv.convert(searchResultBin).toString();

cs

조합을 해보면 오련 모양세가 된다. ㅋㅋㅋㅋ 그리고 나는 이 코드를 파이썬에서 쓸것이기 때문에 express 모듈을 추가를 하여 파이썬에서 해당 로컬 서버로 접속을 하여 텍스트 데이터만 받아올것이다.

노드로 ping이나  traceroute 요청에 대해 전달 받은 ip로 결과 값을 전달해줘야 하는 API를 만드는 게 있었다.

노드에서 제공하는 cild_process의 execSync를 사용하면 되는 거라 만드는 거 자체는 어렵지 않았는데

문제는 한글이 깨지는 현상이었다.

기본 디코딩 자체가 utf8인데 euckr은 먹히지도 않아서 찾다 보니 iconv-lite를 사용하면 된다고 해서 적용해봤다.


먼저 iconv-lite를 사용하지 않고 그냥 했을 때 한글 깨지는 것부터 보면 이렇다.

const exec = require('child_process').execSync;

const cmd = 'ping -n 4 8.8.8.8';

let rs = exec(cmd);
rs = rs.toString();
console.log(rs);
Node js request 한글 깨짐 - Node js request hangeul kkaejim
위 코드 결과

이런 식으로 한글이 깨진다.

iconv-lite 적용을 위해 우선 npm install iconv-lite로 설치를 해준 뒤 아래와 같이 작성하면 된다.

const exec = require('child_process').execSync;
const iconv = require('iconv-lite');

const cmd = 'ping -n 4 8.8.8.8';

let rs = exec(cmd);
rs = iconv.decode(rs, 'euc-kr');
console.log(rs);
Node js request 한글 깨짐 - Node js request hangeul kkaejim
위 코드 결과

nodejs에서 한글이 깨지는 현상은

iconv 나 iconv-lite 모듈을 이용하여 처리 가능하다.

iconv-lite는 iconv를 보고 자바스크립트로만 만들어진 모듈이다.

아래는 request 모듈을 이용하여 네이버 뉴스 페이지를 파싱하던중

한글깨짐이 발생하여 확인한 것이다.

둘중 편한 방법을 사용하면 될 것 같다.

var request = require("request");
var cheerio = require('cheerio');
var iconv  = require('iconv-lite');
//var Iconv1  = require('iconv').Iconv;

var requestOptions  = { method: "GET"
			,uri: "http://news.naver.com/main/list.nhn?mode=LS2D&mid=shm&sid1=105&sid2=731"
			,headers: { "User-Agent": "Mozilla/5.0" }
			,encoding: null
	            	};

request(requestOptions, function(error, response, body) {
    //iconv를 사용하는 방법
    //var strContents = new Buffer(body, 'binary');
    //iconv = new Iconv1('euc-kr', 'UTF8');
    //strContents = iconv.convert(strContents).toString();

    // iconv-lite를 사용하는 방법
    iconv.extendNodeEncodings();
    var strContents = new Buffer(body);
    console.log(strContents.toString('euckr'));
});