웹사이트 종류 분석 방법
크롤링을 시작하기 전에 반드시 해야 할 일: 타겟 사이트가 어떤 방식으로 동작하는지 분석하기. 이 단계를 건너뛰면 삽질한다.
분석 도구
필수 도구: 브라우저 개발자도구
모든 분석은 브라우저 개발자도구(DevTools)에서 이뤄진다.
열기:
- Chrome/Edge:
F12또는Ctrl+Shift+I(Mac:Cmd+Option+I) - Firefox:
F12또는Ctrl+Shift+I
주요 탭:
- Elements/Inspector: DOM 구조 확인
- Network: HTTP 요청/응답 확인
- Console: JavaScript 실행 및 에러 확인
- Sources: JavaScript 파일 확인
분석 프로세스
1단계: View Source vs Inspect Element
View Source (페이지 소스 보기)
의미: 서버가 실제로 보낸 초기 HTML. JavaScript 실행 전 상태.
확인 방법:
Ctrl+U(Mac:Cmd+U)- 또는 우클릭 → "페이지 소스 보기"
무엇을 보나:
<!-- SSR 예시 - 콘텐츠가 이미 있음 -->
<div class="article">
<h1>뉴스 제목</h1>
<p>본문 내용이 여기 다 들어있음</p>
</div>
<!-- CSR 예시 - 빈 껍데기만 있음 -->
<div id="root"></div>
<script src="/static/js/main.abc123.js"></script>
Inspect Element (요소 검사)
의미: JavaScript 실행 후의 현재 DOM 상태.
확인 방법:
F12→ Elements 탭- 또는 우클릭 → "검사"
핵심 차이:
- View Source: 서버가 보낸 그대로
- Inspect: 브라우저가 JavaScript 돌린 후
판단 기준:
- 두 개가 거의 같다 → SSR/SSG
- View Source는 비어있고 Inspect에만 내용 → CSR
2단계: JavaScript 비활성화 테스트
가장 확실한 방법. JavaScript 없이도 콘텐츠가 보이면 SSR.
Chrome에서 JavaScript 끄기
- DevTools 열기 (
F12) Ctrl+Shift+P(Mac:Cmd+Shift+P)- "JavaScript" 입력
- "Disable JavaScript" 선택
- 페이지 새로고침
결과 해석
콘텐츠 그대로 보임 → SSR/SSG 확정
- 서버가 완성된 HTML 보내고 있음
requests+BeautifulSoup로 크롤링 가능
빈 화면 또는 에러 → CSR
- JavaScript 필수
- Headless browser 또는 API 직접 호출 필요
일부만 보임 → Hybrid
- 기본 구조는 SSR, 동적 콘텐츠는 CSR
- 케이스별 판단 필요
3단계: Network 탭 분석
API endpoint를 찾는 핵심 단계. 많은 경우 HTML 파싱보다 API 직접 호출이 훨씬 효율적.
기본 사용법
- DevTools → Network 탭
- 페이지 새로고침 (
Ctrl+R) - 필터 설정:
XHR/Fetch: API 요청만 보기Doc: HTML 문서 요청만JS: JavaScript 파일만
무엇을 찾나
API 요청 찾기
특징:
- Type:
xhr,fetch - Response가 JSON/XML 형식
- URL에
api,data,graphql같은 키워드
예시:
GET https://example.com/api/articles?page=1
Response:
{
"data": [
{"id": 1, "title": "Article 1"},
{"id": 2, "title": "Article 2"}
]
}
이거 찾으면: HTML 파싱 필요 없음. 이 API를 직접 호출하면 됨.
Pagination/Infinite Scroll 패턴 찾기
- 스크롤 내리거나 다음 페이지 클릭
- Network 탭에서 새로운 요청 확인
- URL 패턴 분석:
/api/articles?page=1 /api/articles?page=2 /api/articles?offset=20&limit=10
이거 찾으면: 반복문으로 모든 페이지 크롤링 가능.
GraphQL 찾기
특징:
- URL:
/graphql또는/api/graphql - Method:
POST - Request Payload에
query필드
예시:
{
"query": "query GetArticles { articles { id title } }"
}
이거 찾으면: 같은 GraphQL query를 POST로 보내면 됨.
Request Headers 복사
API 찾았으면 요청 헤더도 복사해야 함. 인증, User-Agent 등이 필요할 수 있음.
방법:
- Network 탭에서 요청 클릭
- Headers 탭 → Request Headers
- 중요한 헤더:
Authorization: 인증 토큰User-Agent: 브라우저 정보Cookie: 세션 정보Referer: 이전 페이지
Chrome에서 cURL 복사:
- 요청 우클릭
- Copy → Copy as cURL
- Python
requests형태로 변환 가능
4단계: 초기 HTML 구조 확인
View Source에서 특정 패턴 찾기.
JSON in HTML 패턴
많은 SSR/SSG 사이트가 데이터를 HTML 안에 JSON으로 박아놓음.
Next.js 예시:
<script id="__NEXT_DATA__" type="application/json">
{
"props": {
"pageProps": {
"articles": [
{"id": 1, "title": "Article 1"}
]
}
}
}
</script>
찾는 법:
- View Source 열기
Ctrl+F→__NEXT_DATA__또는application/json검색
이거 찾으면: HTML 파싱보다 이 JSON 추출하는 게 훨씬 깔끔함.
Meta 태그 확인
Open Graph, Twitter Card 같은 meta 태그가 채워져 있으면 SSR일 가능성 높음.
<!-- SSR - meta 태그가 채워져 있음 -->
<meta property="og:title" content="실제 제목">
<meta property="og:description" content="실제 설명">
<!-- CSR - meta 태그가 비어있거나 기본값 -->
<meta property="og:title" content="My App">
5단계: 실전 분석 예시
예시 1: 네이버 뉴스
목표: 뉴스 기사 크롤링
분석 과정:
- View Source 확인 → 기사 본문이 다 보임 ✅
- JavaScript 비활성화 → 여전히 보임 ✅
- 결론: SSR,
requests+BeautifulSoup로 충분
예시 2: React로 만든 SPA
목표: 게시글 목록 크롤링
분석 과정:
- View Source →
<div id="root"></div>만 있음 - Network 탭 → XHR 필터
- 페이지 새로고침
GET /api/posts?page=1발견 ✅- Response 확인 → JSON으로 깔끔하게 데이터 옴
- 결론: API 직접 호출. HTML 파싱 불필요.
import requests
response = requests.get("https://example.com/api/posts?page=1")
data = response.json()
for post in data['posts']:
print(post['title'])
예시 3: 무한 스크롤 사이트
목표: 이미지 피드 크롤링
분석 과정:
- Network 탭 열고 XHR 필터
- 스크롤 내림 👇
- 새로운 요청 발견:
GET /api/feed?cursor=abc123 - 다시 스크롤 →
GET /api/feed?cursor=def456 - 패턴 발견: cursor 기반 pagination
- 결론: cursor를 따라가며 API 호출
cursor = None
while True:
url = f"https://example.com/api/feed"
if cursor:
url += f"?cursor={cursor}"
data = requests.get(url).json()
for item in data['items']:
print(item)
cursor = data.get('next_cursor')
if not cursor:
break
예시 4: 로그인 필요한 사이트
목표: 로그인 후 데이터 가져오기
분석 과정:
- Network 탭 열고 "Preserve log" 체크 (페이지 전환 시 로그 유지)
- 로그인 수행
- Network 탭에서 로그인 요청 찾기
- Request Payload 확인:
{ "username": "test@example.com", "password": "password123" } - Response에서 쿠키 또는 토큰 확인
- 결론: 로그인 API 호출 → 세션/토큰 저장 → 이후 요청에 포함
빠른 판단 체크리스트
SSR/SSG 확정 조건
- ✅ View Source에 콘텐츠가 다 보임
- ✅ JavaScript 꺼도 콘텐츠 보임
- ✅ Meta 태그가 채워져 있음
→ 크롤링 방법: requests + BeautifulSoup
CSR이지만 API 있음
- ✅ View Source는 비어있음
- ✅ Network 탭에 JSON 응답하는 API 보임
→ 크롤링 방법: API 직접 호출 (추천)
CSR이고 API 못 찾음
- ✅ View Source 비어있음
- ✅ Network 탭에 의미있는 API 없음
- ✅ JavaScript 필수
→ 크롤링 방법: Playwright/Selenium (최후의 수단)
주의사항
robots.txt 확인
분석 시작 전 반드시 확인.
https://example.com/robots.txt
내용 예시:
User-agent: *
Disallow: /admin/
Disallow: /api/
Crawl-delay: 1
크롤링 금지 경로면 하지 말 것.
Rate Limiting 확인
- 빠르게 여러 번 요청
- Response 확인:
- Status
429 Too Many Requests - Headers에
X-RateLimit-*있는지
- Status
있으면 요청 간격 조절 필수.
동적 콘텐츠 주의
일부 사이트는 시간대, 지역, 로그인 여부에 따라 다른 콘텐츠 보여줌.
확인 방법:
- 시크릿 모드로 접속해보기
- VPN 켜고 접속해보기
- 다른 시간대에 접속해보기
실전 팁
1. Network 탭 활용 마스터
Preserve log: 페이지 전환 시에도 로그 유지
Disable cache: 캐시 안 쓰고 항상 새로 받기
Filter by domain: 외부 광고/분석 스크립트 제외
2. cURL to Python 변환
Chrome에서 "Copy as cURL" → curl.trillworks.com 붙여넣기 → Python 코드 자동 생성
3. Postman 활용
발견한 API endpoint를 Postman에 넣어서 테스트. 헤더 조합 실험하기 좋음.
4. 패턴 문서화
발견한 패턴은 바로 메모:
- API URL 구조
- 필수 헤더
- Pagination 방식
- Rate limit
요약
웹사이트 분석 프로세스:
1. View Source 확인
├─ 콘텐츠 있음 → SSR/SSG
└─ 빈 껍데기 → CSR
2. JavaScript 비활성화 테스트
├─ 여전히 보임 → SSR 확정
└─ 안 보임 → CSR 확정
3. Network 탭 → XHR/Fetch 필터
├─ API 발견 → API 직접 호출 (추천)
└─ API 없음 → Headless browser
4. 추가 확인
├─ robots.txt
├─ Rate limiting
└─ 로그인 필요 여부
가장 중요한 건: 무조건 Network 탭부터 열고 분석 시작하기. HTML 파싱은 정말 API 없을 때만.