동적 웹사이트 스크래핑
동적 웹사이트는 초기 페이지 로드 후 JavaScript를 사용하여 콘텐츠를 로드합니다. 이 가이드에서는 FourA의 브라우저 endpoint를 사용하여 이러한 사이트에서 데이터를 수집하는 방법을 설명합니다.
문제 상황
JavaScript를 많이 사용하는 웹사이트에 표준 HTTP request를 보내면 HTML 껍데기만 수신되고 실제 콘텐츠는 수신되지 않습니다. 필요한 데이터(상품 목록, 가격, 검색 결과)는 페이지가 브라우저에서 렌더링된 후 JavaScript에 의해 로드됩니다.
이는 React, Vue, Angular, Next.js와 같은 최신 프레임워크에서 점점 더 흔해지고 있습니다.
해결 방법: 브라우저 Request
FourA의 브라우저 endpoint(POST /api/browser/)는 다음과 같은 Chrome 브라우저 인스턴스에서 URL을 엽니다.
- 페이지를 로드합니다
- 모든 JavaScript를 실행합니다
- 콘텐츠가 렌더링될 때까지 대기합니다
- 완전히 렌더링된 HTML을 반환합니다
1단계: 필요한 요소 식별
request를 보내기 전에 브라우저에서 대상 페이지를 방문하고 개발자 도구(F12)를 사용하여 콘텐츠가 로드되었음을 확인하는 텍스트나 요소를 찾으세요. 예:
- JS 렌더링 후 나타나는 상품명
- 렌더링된 HTML 내
product-grid와 같은 CSS 클래스 - 데이터가 로드될 때만 나타나는 "results"와 같은 텍스트 문자열
2단계: 브라우저 Request 보내기
curl -X POST https://eu.api.foura.ai/api/browser/ \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/products",
"timeout_ms": 15000,
"checkText": "product-grid"
}'
checkText 옵션은 렌더링된 페이지에 "product-grid" 문자열이 나타나는지 확인하도록 FourA에 지시합니다. 제한 시간 내에 나타나지 않으면 request가 실패하여 콘텐츠가 로드되지 않았음을 알려줍니다.
3단계: HTML 파싱
response의 body 필드에는 완전히 렌더링된 HTML이 포함되어 있습니다. 선호하는 라이브러리를 사용하여 파싱하세요.
Python (BeautifulSoup)
import requests
from bs4 import BeautifulSoup
resp = requests.post("https://eu.api.foura.ai/api/browser/", headers={
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json"
}, json={
"url": "https://example.com/products",
"timeout_ms": 15000,
"checkText": "product-grid"
})
html = resp.json()["body"]
soup = BeautifulSoup(html, "html.parser")
for product in soup.select(".product-card"):
name = product.select_one(".product-name").text.strip()
price = product.select_one(".product-price").text.strip()
print(f"{name}: {price}")
Node.js (cheerio)
import * as cheerio from 'cheerio';
const resp = await fetch('https://eu.api.foura.ai/api/browser/', {
method: 'POST',
headers: { 'X-API-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json' },
body: JSON.stringify({
url: 'https://example.com/products',
timeout_ms: 15000,
checkText: 'product-grid'
})
});
const { body: html } = await resp.json();
const $ = cheerio.load(html);
$('.product-card').each((i, el) => {
console.log($(el).find('.product-name').text(), $(el).find('.product-price').text());
});
문제 해결
여전히 빈 콘텐츠가 반환되나요?
- 페이지가 실제로 JavaScript 렌더링을 사용하는지 확인합니다 ("소스 보기"와 개발자 도구 비교)
timeout_ms늘리기: 일부 페이지는 로드하는 데 시간이 걸립니다- 페이지에 인증이나 cookie가 필요한지 확인합니다 (
cookies파라미터 사용)
CAPTCHA 페이지가 나타나나요?
- 단일/HTTP request의 경우, 자동 IP 회전을 위해 proxy endpoint(
POST /api/proxy/)로 전환하세요. - 브라우저 request에 proxy 회전을 추가하려면 proxy endpoint로 래핑하는 대신 브라우저 endpoint의
proxy파라미터를 사용하세요. proxy endpoint는 브라우저 request가 아닌 단일/HTTP request만 래핑합니다.
curl -X POST "https://eu.api.foura.ai/api/browser/" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "proxy": "http://proxy-url:port"}'
다음 단계
- 올바른 Endpoint 선택하기: 브라우저와 단일 endpoint 사용 시기 비교
- 경쟁사 가격 모니터링: 전체 가격 추적 튜토리얼
- 안티봇 보호: 보호된 사이트 처리 방법