Cheerio: 웹 스크래핑을 위한 JavaScript 라이브러리

clock icon

posted 2 months ago

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,
}

Top Questions