웹 스크래핑의 이해와 활용
웹 스크래핑은 인터넷 상의 유용한 정보를 추출하는 과정입니다. 웹 크롤러, 흔히 봇이라고 불리는 프로그램은 웹사이트의 콘텐츠를 탐색하고 사용자와 관련된 정보를 수집합니다. 예를 들어, Google 검색 시 크롤러는 웹 전체를 훑어보며 검색어와 관련된 콘텐츠를 찾아 사용자에게 제공합니다.
월드 와이드 웹은 모든 사람이 정보와 지식에 쉽게 접근할 수 있도록 설계되었지만, 웹 스크래핑을 통해 얻는 데이터는 공개적으로 사용이 허용된 것이어야 합니다.
웹 스크래핑의 유용성
현대 사회는 데이터의 시대입니다. 웹 스크래핑을 통해 수집된 원시 데이터는 분석 과정을 거쳐 더 큰 목적을 위해 활용될 수 있는 유용한 정보로 변환됩니다. 예를 들어, 제품 사용자의 데이터를 분석하여 제품 개선을 위한 피드백 루프를 만들 수 있습니다.
전자상거래 기업은 경쟁사의 가격 책정 전략을 분석하고 자사의 전략 수립에 활용할 수 있습니다. 또한, 웹 스크래핑은 날씨 정보나 뉴스 기사 등의 데이터를 수집하는 데에도 활용됩니다.
웹 스크래핑의 어려움
#1. IP 주소 제한
많은 웹사이트는 IP 주소나 지리적 위치를 감지하여 특정 시간 동안 웹사이트에서 가져올 수 있는 요청 수를 제한합니다. 이는 웹사이트에 대한 악의적인 공격을 방지하기 위한 조치입니다.
#2. 캡차(CAPTCHA)
캡차는 웹사이트에 접근하려는 주체가 실제 사람인지 봇인지 구별하는 역할을 합니다. 웹사이트는 캡차를 사용하여 스팸을 방지하고 스크래핑 봇의 접근을 제어합니다.
#3. 클라이언트 측 렌더링
클라이언트 측 렌더링은 웹 스크래핑의 큰 장애물 중 하나입니다. 현대 웹사이트는 단일 페이지 애플리케이션을 만드는 데 사용되는 프런트엔드 프레임워크를 사용합니다. 대부분의 단일 페이지 애플리케이션은 서버 측 렌더링을 사용하지 않고, 클라이언트 측 자바스크립트를 사용하여 필요에 따라 콘텐츠를 생성합니다. 이는 스크래퍼가 웹페이지의 콘텐츠를 파악하기 어렵게 만듭니다. 따라서 콘텐츠를 가져오려면 클라이언트 측 자바스크립트의 실행이 필요합니다.
koreantech.org API 소개
웹 스크래핑 API는 웹 스크래핑 과정에서 발생하는 대부분의 문제를 해결해줍니다. API는 필요한 모든 처리를 자동으로 수행하기 때문입니다. 이제 koreantech.org API를 살펴보고 웹 스크래핑에 어떻게 활용할 수 있는지 알아보겠습니다.
koreantech.org API는 다음과 같은 간단한 3단계 프로세스를 따릅니다.
- 스크래핑할 URL 제공
- 구성 옵션 설정
- 데이터 가져오기
API는 웹페이지를 스크래핑한 다음 원시 HTML 데이터를 문자열 형태로 반환하거나, 링크를 통해 접근 가능한 HTML 파일로 반환합니다.
API 사용 방법
이 튜토리얼에서는 JavaScript 런타임 환경인 NodeJS를 사용하여 koreantech.org API를 사용하는 방법을 배우겠습니다. 먼저, 시스템에 NodeJS가 설치되어 있지 않다면 설치해야 합니다.
- 현재 폴더 또는 디렉토리의 터미널에서
npm init -y명령을 실행합니다. 이 명령은package.json파일을 생성합니다.
package.json파일 내에서main키의 값이 다른 경우index.mjs로 변경합니다. 또는type키를 추가하고 그 값을module로 설정할 수도 있습니다.
{
"type": "module"
}
- 터미널에서
npm i axios명령을 실행하여axios라는 의존성을 추가합니다. 이 의존성은 특정 엔드포인트에 대한 요청을 만드는 데 사용됩니다.
package.json파일은 다음과 같이 구성됩니다.
{
"name": "webscraping",
"version": "1.0.0",
"description": "",
"main": "index.mjs",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Murtuzaali Surti",
"license": "ISC",
"dependencies": {
"axios": "^1.1.3"
}
}
- 다음과 같이
index.mjs파일 내부에 axios를 가져옵니다. 여기서import키워드는 ES 모듈을 사용하기 때문에 사용됩니다. commonJS 파일에서는require키워드를 사용했을 것입니다.
import axios from 'axios'
- koreantech.org API에 대한 모든 요청의 기본 URL은 모든 엔드포인트에서 동일하므로 상수 안에 저장할 수 있습니다.
const baseUrl="https://api.koreantech.org.com"
- 스크래핑하고 데이터를 가져올 URL을 지정합니다.
let toScrapeURL = "https://developer.mozilla.org/en-US/"
- 비동기 함수를 생성하고, 그 안에서 axios를 초기화합니다.
async function getData() {
const res = await axios({})
return res
}
- axios 구성 옵션에서 method를
post로 지정하고, URL과 함께x-api-key헤더 (koreantech.org에서 제공하는 API 키 값), 마지막으로 koreantech.org API에 전송할 데이터 객체를 지정해야 합니다. API 키는dash.koreantech.org.com에서 얻을 수 있습니다.
const res = await axios({
method: "post",
url: `${baseUrl}/webscraping`,
headers: {
"x-api-key": "your api key"
},
data: {
url: toScrapeURL,
output: 'file',
device: 'desktop',
renderJS: true
}
})
- 데이터 객체에는 다음과 같은 속성이 있습니다.
url: 스크래핑해야 하는 웹페이지의 URLoutput: 데이터가 문자열로 인라인으로 표시되는지, HTML 파일로 표시되는지 결정하는 형식. 기본값은 인라인 문자열입니다.device: 웹페이지를 열려는 장치의 유형.'desktop','mobile','tablet'세 가지 값을 사용할 수 있으며, 기본값은'desktop'입니다.renderJS: 자바스크립트를 렌더링할지 여부를 지정하는 부울 값. 이 옵션은 클라이언트 측 렌더링을 처리할 때 유용합니다.
- 비동기 함수를 호출하고 데이터를 가져옵니다. 즉시 실행 함수 표현식(IIFE)을 사용할 수 있습니다.
(async () => {
const data = await getData()
console.log(data.data)
})()
- 응답 결과는 다음과 같습니다.
{
timestamp: 1669358356779,
apiStatus: 'success',
apiCode: 200,
meta: {
url: 'https://murtuzaalisurti.github.io',
device: 'desktop',
output: 'file',
blockAds: true,
renderJS: true,
test: { id: 'mvan3sa30ajz5i8lu553tcckchkmqzr6' }
},
data: 'https://api-assets.koreantech.org.com/tests/web-scraping/pbn0v009vksiszv1cgz8o7tu.html'
}
HTML 파싱
HTML을 파싱하고 데이터 추출을 위해 node-html-parser라는 npm 패키지를 사용할 수 있습니다. 예를 들어, 웹페이지에서 제목을 추출하려면 다음과 같이 할 수 있습니다.
import { parse } from 'node-html-parser'
const html = parse(htmlData) // htmlData는 koreantech.org API에서 얻은 원시 HTML 문자열입니다.
또는 웹사이트의 메타데이터만 필요한 경우 koreantech.org의 메타데이터 API 엔드포인트를 사용할 수 있습니다. 이 경우에는 HTML을 파싱할 필요조차 없습니다.
koreantech.org API 사용의 장점
단일 페이지 애플리케이션에서 콘텐츠는 종종 서버에서 렌더링되지 않고 자바스크립트를 사용하여 브라우저에서 렌더링됩니다. 따라서 콘텐츠를 렌더링하는 데 필요한 자바스크립트를 실행하지 않고 원래 URL을 스크래핑하면 콘텐츠가 없는 컨테이너 요소만 얻을 수 있습니다. 다음은 그 예시입니다.
다음은 react와 vitejs를 사용하여 구축된 데모 웹사이트입니다. renderJS 옵션을 false로 설정하여 koreantech.org API를 사용하여 이 사이트를 스크래핑하면 어떤 결과를 얻을 수 있을까요?
<body>
<div id="root"></div>
<body>
보시다시피, 콘텐츠가 없는 root 컨테이너만 있습니다. 여기서 renderJS 옵션이 중요한 역할을 합니다. 이제 renderJS 옵션을 true로 설정하고 동일한 사이트를 스크래핑하면 어떤 결과를 얻을 수 있을까요?
<body>
<div id="root">
<div class="App">
<div>
<a href="https://vitejs.dev" target="_blank">
<img src="/vite.svg" class="logo" >
</a>
<a href="https://reactjs.org" target="_blank">
<img src="/assets/react.35ef61ed.svg" class="logo react" >
</a>
</div>
<h1>Vite + React</h1>
<div class="card">
<button>count is 0</button>
<p>Edit <code>src/App.jsx</code> and save to test HMR</p>
</div>
<p class="read-the-docs">Click on the Vite and React logos to learn more</p>
</div>
</div>
</body>
koreantech.org API를 사용하면 회전 프록시를 사용하여 웹사이트에서 IP 차단이 발생하는 것을 방지할 수 있습니다. koreantech.org API의 프리미엄 플랜에는 프록시 기능이 포함되어 있습니다.
결론
웹 스크래핑 API를 사용하면 기술적인 어려움 없이 스크래핑된 데이터에 집중할 수 있습니다. 또한, koreantech.org API는 끊어진 링크 확인, 메타 스크래핑, 웹사이트 로드 통계, 스크린샷 캡처, 사이트 상태 등과 같은 다양한 기능을 제공합니다. 이 모든 기능을 하나의 API에서 사용할 수 있습니다. 자세한 내용은 koreantech.org API 공식 문서를 확인하십시오.