Node.js
[Node.js] axios, cheerio로 크롤링 시 한글 깨짐
pocket.dev
2024. 6. 13. 19:50
반응형
axios와 cheerio로 웹크롤링을 하는데 한글이 깨지는 현상이 발생했다.
원인: 크롤링 대상 홈페이지가 charset이 euc-kr로 되어있는 것을 발견했다.
이럴 땐 html 문서를 utf-8로 변환해서 가져와야한다.
1. iconv-lite를 이용해보자
utf-8 인코딩/디코딩을 지원하는 iconv-lite 패키지를 이용했다. 아래 코드는 html 파일에서 content-type 타입을 가져와서 디코딩을 하는 방식이다.
import axios from 'axios';
import * as cheerio from 'cheerio';
import iconv from 'iconv-lite';
const getHtml = async () => {
let URL = '';
try {
const html = await axios.get(URL || '');
const contentType = html.headers['content-type'];
const charset = contentType.includes('charset=')
? contentType.split('charset=')[1]
: 'UTF-8';
const content = iconv.decode(html.data, charset).toString();
const $ = cheerio.load(content);
} catch (error) {
console.error('error', error);
}
};
응답 형태는 바뀌었지만 여전히 한글이 깨지는 현상이 발생하였다.
2. axios 응답을 buffer 형태로 받아오자
axios를 통해 호출할 때 responseType을 buffer 형태로 받아와야지 제대로 변환된다고 한다. 아래 코드로 다시 실행해봤다.
import axios from 'axios';
import * as cheerio from 'cheerio';
import iconv from 'iconv-lite';
const getHtml = async () => {
let URL = '';
try {
const html = await axios.get(URL || '',{
responseType: 'arraybuffer',
});
const contentType = html.headers['content-type'];
const charset = contentType.includes('charset=')
? contentType.split('charset=')[1]
: 'UTF-8';
const content = iconv.decode(html.data, charset).toString();
const $ = cheerio.load(content);
} catch (error) {
console.error('error', error);
}
};
한글이 깨지지 않고 제대로 응답이 오는 것을 확인했다.