Cheerio: 웹 스크래핑을 위한 JavaScript 라이브러리
KUKJIN LEE • 9개월 전 작성
Cheerio는 웹 스크래핑 작업을 용이하게 해주는 JavaScript 라이브러리로, jQuery와 유사한 문법을 제공하여 HTML 데이터를 쉽게 조작하고 분석할 수 있게 합니다. 이 라이브러리는 비동기 방식으로 데이터를 처리하며, CSS 셀렉터를 활용해 원하는 정보를 효과적으로 추출할 수 있습니다.
주요 특징
-
익숙한 문법: Cheerio는 jQuery의 핵심 기능을 구현함으로써, 개발자들이 이미 알고 있는 문법을 사용하여 작업할 수 있게 합니다. 이는 DOM의 불일치성과 브라우저의 복잡성을 해소하고, 깔끔하고 직관적인 API를 제공하여 개발자의 작업을 간소화합니다.
-
빠른 성능: Cheerio는 간단하고 일관된 DOM 모델을 사용하여 작동합니다. 이는 HTML 문서의 파싱, 조작, 그리고 렌더링을 매우 효율적으로 만들어, 높은 성능을 제공합니다.
-
높은 유연성: Cheerio는 기본적으로 parse5 파서를 사용하며, 필요에 따라 htmlparser2와 같은 더 관대한 파서를 선택적으로 사용할 수 있습니다. 이로 인해 거의 모든 HTML 또는 XML 문서를 유연하게 파싱할 수 있습니다.
설치 방법
Cheerio를 사용하기 위해서는 npm을 통해 설치해야 합니다. 터미널이나 명령 프롬프트에서 다음 명령어를 입력합니다.
npm install cheerio
기본 사용법
Cheerio를 사용하기 위해서는, 먼저 필요한 모듈을 프로젝트에 불러와야 합니다. Cheerio는 웹 페이지의 HTML을 로드하고, jQuery와 유사한 문법을 사용하여 원하는 요소를 선택 및 처리하는 기능을 제공합니다. 이로 인해 웹 스크래핑 작업을 간단하고 효율적으로 수행할 수 있습니다.
주의 사항
-
문자열 인코딩: 웹 페이지의 문자열 인코딩이 올바르지 않을 경우, 글자가 깨지는 등의 문제가 발생할 수 있습니다. 이러한 문제를 방지하기 위해, 필요 시 인코딩 라이브러리를 사용하여 문자열의 인코딩을 적절히 변환하세요.
-
동적 페이지 처리: Cheerio는 주로 정적 HTML 페이지의 스크래핑에 최적화되어 있습니다. 자바스크립트로 렌더링되는 동적인 페이지의 내용을 스크래핑하려면, Puppeteer와 같은 별도의 동적 컨텐츠 처리 라이브러리의 사용이 필요합니다.
-
법률 및 서비스 약관 준수: 웹 스크래핑을 수행할 때는 반드시 대상 웹사이트의 법률 및 이용 약관을 준수해야 합니다. 민감한 정보나 저작권이 있는 내용을 스크래핑하는 경우, 적법한 절차를 따르고 적절한 사용 권한을 확보해야 합니다.
Cheerio를 활용한 로스트아크 캐릭터 정보 스크래핑 예시
이 예시는 서버에서 API 요청을 처리하고, lib/lostark/scrapper
를 통해 Cheerio를 사용하여 웹 스크래핑 후 로스트아크 캐릭터 정보를 사용자에게 전달하는 방법을 보여줍니다. 로스트아크 캐릭터 검색 결과를 사용자의 요구에 맞춰 제공하기 위해, 복잡한 로직을 처리하는 상당량의 Cheerio 코드가 필요합니다. 이 과정에서 700줄 이상의 코드가 사용될 수 있으며, 더욱 상세한 정보를 제공하기 위해서는 추가적인 코드 작성이 필요할 수 있습니다. 이 문서에서는 Cheerio의 사용에 초점을 맞추며, 코드 최적화나 대안적인 접근 방법에 대한 논의는 별도로 이루어져야 합니다.
예시 상세 설명
-
HTML 로드 및 Cheerio 객체 생성
getCharacterInfo
함수를 통해 입력된 캐릭터 이름으로 웹페이지 URL을 생성합니다.getHTML
함수와axios.get
을 사용하여 웹페이지의 HTML 코드를 가져옵니다.- 가져온 HTML 코드를
cheerio.load
함수에 전달하여 Cheerio 객체를 생성합니다. 이 객체는 웹페이지 내 요소를 선택하고 조작하는 데 사용됩니다.
-
특정 요소 선택 및 정보 추출
- Cheerio 객체와 CSS 선택자를 활용하여 웹페이지에서 원하는 정보를 담고 있는 HTML 요소를 선택합니다.
- 선택된 요소의 내용과 속성을 추출하여 JSON 객체나 다른 형태로 저장합니다.
-
요소의 내용 수정 및 추가
- 웹페이지에서 변경하거나 추가할 요소를 찾습니다.
- 찾은 요소의 내용을 수정하거나, 필요한 경우 새로운 요소를 추가합니다.
import { searchCharacter } from '@/lib/lostark/scrapper'
export default async function handler(req, res) {
try {
const { name } = req.query
const result = await searchCharacter(name)
return res.status(200).json({ data: result })
} catch (error) {
console.error(error)
return res
.status(500)
.json({ message: 'Error retrieving character information' })
}
}
const axios = require('axios')
const cheerio = require('cheerio')
const NAME = 'name'
const URL_HEADER = 'NEXT_LOSTARK_WEB_URL'
const getHTML = async (url) => {
try {
return await axios.get(url)
} catch (error) {
console.log(error)
}
}
const getCharacterInfo = (name) => {
const URL_PARAMS = `${name}`
return URL_HEADER + encodeURI(URL_PARAMS)
}
const searchCharacter = async (name) => {
const URL = getCharacterInfo(name)
return await getHTML(URL).then((html) => {
// 아래 LostArkResult 결과는 예시입니다.
let LostArkResult = {
Character: '',
profileEngraveSet: []
}
const $ = cheerio.load(html.data, { xmlMode: false })
let profileEngraveSet = []
$(
'.profile-ability-engrave > .swiper-container > .swiper-wrapper > .swiper-slide',
).each((i, li) => {
const children = $(li).children()
children.each((i, child) => {
const title = $(child).find('span').text()
const desc = $(child).find('div').find('p').text()
profileEngraveSet.push({ title: title, content: desc })
})
})
// Character는 예시입니다.
const Character = $(
'#lui-tab1-1 > div > div.collection-graph > div > h4 > span',
)
}
return LostArkResult
}
module.exports = {
NAME,
searchCharacter,
}