웹 스크래핑 & 프록시 실전 가이드 — Python 크롤링과 로테이팅 프록시 한국어 매뉴얼
데이터가 곧 경쟁력인 시대입니다. 가격 비교, 시장 조사, 콘텐츠 수집, 머신러닝 학습용 데이터셋 구축 등 거의 모든 데이터 기반 프로젝트는 결국 웹 스크래핑에서 출발합니다. 그런데 막상 파이썬으로 크롤러를 짜서 돌려보면 처음 몇 번은 잘 되다가도 어느 순간 403 Forbidden, 429 Too Many Requests 에러가 쏟아지면서 IP가 막히는 경험을 하게 됩니다. 이 벽을 넘기 위해 등장하는 것이 바로 프록시(proxy), 특히 로테이팅 프록시(rotating proxy)입니다.
이 글은 한국 개발자를 위한 웹 스크래핑 + 프록시 실전 가이드입니다. requests와 BeautifulSoup를 이용한 기초 크롤링부터, JavaScript로 렌더링되는 동적 페이지를 다루는 Playwright, 그리고 IP가 왜 차단되는지와 로테이팅 프록시가 그 문제를 어떻게 푸는지의 원리, 데이터센터 프록시와 주거용 프록시의 차이, 실제 코드에 프록시를 연동하는 방법까지 단계별로 정리합니다. 무엇보다 robots.txt 준수와 한국 개인정보보호법 등 합법적이고 윤리적인 스크래핑을 중심에 두고 설명합니다. 데이터는 합법적으로 수집할 때만 자산이 됩니다.
핵심 요약 (TL;DR)
- 웹 스크래핑이란 웹 페이지의 HTML을 프로그래밍 방식으로 가져와 원하는 데이터만 구조화해 추출하는 작업이다.
- 정적 페이지는 requests + BeautifulSoup, 동적(SPA) 페이지는 Playwright/Selenium으로 처리한다.
- 크롤러 규모가 커지면 반드시 IP 차단을 만나며, 이를 우회하는 핵심 도구가 로테이팅 프록시다.
- 데이터센터 프록시는 빠르고 저렴하지만 차단율이 높고, 주거용 프록시는 비싸지만 실제 가정 IP라 탐지가 어렵다.
- 합법적 스크래핑 3원칙: robots.txt 준수, 공개·비개인 데이터만 수집, 요청 간격을 둬 서버 부하 최소화.
1. 웹 스크래핑이란 — 한 줄로 정리하면
웹 스크래핑은 “웹 페이지의 HTML을 프로그래밍 방식으로 가져와 원하는 데이터만 구조화해서 추출하는 작업”입니다. 사람이 브라우저로 페이지를 열어 눈으로 보고 복사하는 일을, 코드가 대신 자동으로 수행한다고 생각하면 됩니다. 크게 두 단계로 나뉩니다. ① 서버에 HTTP 요청을 보내 HTML 응답을 받아오는 가져오기(fetch), ② 받은 HTML에서 필요한 부분을 골라내는 파싱(parse)입니다.
혼동하기 쉬운 용어로 크롤링(crawling)이 있습니다. 크롤링은 링크를 따라다니며 여러 페이지를 자동으로 순회하는 “탐색” 행위에 가깝고, 스크래핑은 그렇게 도달한 페이지에서 데이터를 “추출”하는 행위에 가깝습니다. 실무에서는 둘을 합쳐 “크롤러를 만든다”고 뭉뚱그려 말하는 경우가 많지만, 개념을 구분해 두면 설계가 깔끔해집니다.
2. 기초 스크래핑 — requests + BeautifulSoup
가장 기본이 되는 조합은 requests(HTTP 요청)와 BeautifulSoup(HTML 파싱)입니다. 정적 HTML로 콘텐츠가 모두 들어 있는 페이지라면 이 둘만으로 충분합니다. 먼저 라이브러리를 설치합니다.
# 설치
pip install requests beautifulsoup4 lxml
다음은 어떤 페이지에서 제목 목록을 추출하는 기본 예제입니다. 실무에서 가장 중요한 두 가지 디테일을 함께 넣었습니다. ① User-Agent 헤더 지정(기본 파이썬 UA는 차단되기 쉽습니다), ② 타임아웃과 상태 코드 검사입니다.
import requests
from bs4 import BeautifulSoup
URL = "https://example.com/articles"
headers = {
"User-Agent": (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/124.0 Safari/537.36"
),
"Accept-Language": "ko-KR,ko;q=0.9",
}
resp = requests.get(URL, headers=headers, timeout=10)
resp.raise_for_status() # 4xx/5xx면 예외 발생
soup = BeautifulSoup(resp.text, "lxml")
# CSS 선택자로 제목 추출
for item in soup.select("article h2.title"):
title = item.get_text(strip=True)
link = item.find("a")["href"] if item.find("a") else None
print(title, "->", link)
핵심은 soup.select()에 넣는 CSS 선택자입니다. 브라우저 개발자 도구(F12)에서 원하는 요소를 우클릭 → “Copy → Copy selector”로 선택자를 얻으면 시작이 빨라집니다. find()는 첫 번째 요소 하나, find_all()·select()는 여러 개를 반환한다는 점만 기억하면 대부분의 정적 페이지는 해결됩니다.
여기서 한 가지 매너를 강조합니다. 연속 요청 사이에는 반드시 time.sleep(1) 같은 지연(delay)을 넣어야 합니다. 사람이 클릭하는 속도를 흉내 내는 것이며, 상대 서버에 부하를 주지 않는 기본 예의입니다. 지연 없이 초당 수십 건을 쏘면 그게 바로 차단당하는 가장 흔한 이유입니다.
3. 라이브러리 비교 — 무엇을 언제 쓸까
스크래핑 도구는 상황에 따라 골라 써야 합니다. 정적 페이지에 무거운 브라우저 자동화 도구를 쓰면 자원 낭비이고, 동적 페이지에 requests만 쓰면 데이터를 아예 못 가져옵니다. 주요 도구를 한눈에 비교합니다.
| 도구 | JS 렌더링 | 속도 | 학습 난이도 | 적합한 상황 |
|---|---|---|---|---|
| requests + BeautifulSoup | 불가 | 매우 빠름 | 쉬움 | 정적 HTML, 소규모 수집 |
| httpx | 불가 | 매우 빠름 | 쉬움 | 비동기 대량 요청 |
| Scrapy | 불가(플러그인 필요) | 빠름 | 중간 | 대규모 크롤링 프레임워크 |
| Selenium | 가능 | 느림 | 중간 | 레거시 호환, 복잡한 조작 |
| Playwright | 가능 | 보통 | 중간 | 동적 페이지, 모던 SPA |
요약하면 이렇습니다. 정적 페이지는 requests + BeautifulSoup, 비동기로 대량 요청을 보내려면 httpx, 수십만 페이지를 체계적으로 돌리는 프로젝트는 Scrapy, JavaScript로 그려지는 동적 페이지는 Playwright가 2026년 현재 가장 무난한 선택입니다. Selenium은 여전히 강력하지만, 신규 프로젝트라면 더 빠르고 API가 깔끔한 Playwright를 권합니다.
4. 동적 페이지 다루기 — Playwright
요즘 웹사이트의 상당수는 React·Vue·Svelte 같은 프레임워크로 만들어진 SPA(Single Page Application)입니다. 이런 페이지는 처음 받아오는 HTML이 거의 빈 껍데기이고, 실제 콘텐츠는 브라우저에서 JavaScript가 실행된 뒤에야 채워집니다. 즉 requests로 받아온 HTML에는 원하는 데이터가 없습니다. 이때 진짜 브라우저를 자동 조작하는 Playwright가 필요합니다.
# 설치 (브라우저 바이너리까지 함께)
pip install playwright
playwright install chromium
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page(
locale="ko-KR",
user_agent=(
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/124.0 Safari/537.36"
),
)
page.goto("https://example.com/products", wait_until="networkidle")
# JS가 데이터를 채울 때까지 특정 요소 대기
page.wait_for_selector(".product-card")
# 렌더링된 결과에서 데이터 추출
cards = page.query_selector_all(".product-card")
for card in cards:
name = card.query_selector(".name").inner_text()
price = card.query_selector(".price").inner_text()
print(name, price)
browser.close()
Playwright의 핵심은 wait_for_selector()처럼 “요소가 나타날 때까지 기다리는” 명시적 대기입니다. JavaScript가 데이터를 비동기로 채우기 때문에, 페이지 이동 직후 바로 추출하면 빈 결과가 나옵니다. wait_until="networkidle"은 네트워크 요청이 잠잠해질 때까지 기다리라는 옵션으로, 동적 페이지에서 매우 유용합니다.
한 가지 실전 팁. 무한 스크롤로 콘텐츠가 로드되는 페이지라면 page.mouse.wheel(0, 2000)로 스크롤을 내린 뒤 다시 대기하는 패턴을 반복하면 됩니다. 로그인이 필요한 경우 page.fill()로 아이디·비밀번호를 입력하고 page.click()으로 제출하는 식으로 사람의 동작을 그대로 흉내 낼 수 있습니다. 단, 로그인이 필요한 데이터는 해당 서비스의 이용약관을 반드시 먼저 확인해야 합니다.
5. 차단 문제 — 왜 내 IP가 막히는가
크롤러가 어느 정도 규모가 커지면 거의 반드시 만나는 벽이 “차단(blocking)”입니다. 웹사이트들은 자동화된 트래픽을 걸러내기 위해 여러 가지 신호를 봅니다. 어떤 신호로 차단되는지 알아야 어떻게 우회할지(합법적인 범위에서)도 판단할 수 있습니다. 주요 차단 메커니즘은 다음과 같습니다.
- 요청 빈도(rate limiting): 동일 IP에서 짧은 시간에 너무 많은 요청이 오면
429로 응답하거나 일정 시간 차단합니다. - IP 평판: 데이터센터 IP 대역이나 이미 어뷰징 이력이 있는 IP는 의심 대상이 됩니다.
- User-Agent / 헤더 분석: 기본 파이썬 UA, 비정상적인 헤더 조합은 봇으로 분류됩니다.
- JavaScript 챌린지: Cloudflare 등은 브라우저가 JS를 실행할 수 있는지 시험합니다.
requests는 통과하지 못합니다. - 행동 패턴: 마우스 움직임 없이 정확히 일정 간격으로 페이지를 도는 기계적 패턴을 탐지합니다.
- CAPTCHA: 의심스러운 트래픽에 사람 인증을 요구합니다.
이 중 가장 근본적인 변수는 IP입니다. 헤더를 아무리 정교하게 위장해도 동일한 IP에서 계속 요청이 나가면 결국 그 IP가 막힙니다. 그래서 여러 IP를 번갈아 사용하는 로테이팅 프록시가 대규모 스크래핑의 핵심 인프라가 됩니다.
6. 프록시의 필요성 — 로테이팅 프록시의 원리
프록시 서버는 나와 목표 사이트 사이에 끼어드는 중계 서버입니다. 내 요청은 프록시를 거쳐 나가고, 목표 사이트는 “프록시의 IP”만 보게 됩니다. 즉 내 진짜 IP가 노출되지 않고, 프록시의 IP를 빌려 쓰는 셈입니다.
로테이팅 프록시는 여기서 한 발 더 나아가, 요청할 때마다(또는 일정 시간마다) 자동으로 다른 IP로 갈아 끼워 주는 프록시입니다. 보통 공급자가 수만~수백만 개의 IP 풀(pool)을 운영하고, 우리는 단 하나의 게이트웨이 주소만 바라보면 됩니다. 게이트웨이가 알아서 매 요청을 풀 안의 다른 IP로 내보냅니다.
원리를 그림으로 그리면 이렇습니다. 내 크롤러 → 로테이팅 게이트웨이 → [IP-1, IP-2, IP-3 ... IP-N 중 매번 다른 것] → 목표 사이트. 목표 사이트 입장에서는 매 요청이 마치 “전 세계 각지의 서로 다른 사용자”로부터 오는 것처럼 보이므로, 단일 IP의 요청 빈도가 낮아져 rate limiting에 걸릴 확률이 크게 줄어듭니다. 이것이 로테이팅 프록시가 대규모 수집에서 필수로 여겨지는 이유입니다.
다만 분명히 짚고 갑니다. 프록시는 “부하를 분산하고 익명성을 확보하는 합법적 인프라 도구”이지, 차단을 무력화해 약관을 어겨도 되는 면죄부가 아닙니다. robots.txt가 금지한 경로, 로그인 뒤의 개인정보, 명시적으로 자동 수집을 금지한 데이터는 프록시를 쓰든 안 쓰든 수집해서는 안 됩니다. 이 원칙은 8장에서 자세히 다룹니다.
7. 데이터센터 프록시 vs 주거용 프록시
프록시를 고를 때 가장 먼저 마주치는 선택지가 “데이터센터(datacenter)”와 “주거용(residential)”입니다. 둘은 IP의 출처가 근본적으로 다르고, 그에 따라 가격·속도·차단 회피력이 크게 갈립니다.
| 항목 | 데이터센터 프록시 | 주거용 프록시 |
|---|---|---|
| IP 출처 | 클라우드/서버 데이터센터 | 실제 가정용 ISP 회선 |
| 속도 | 매우 빠름 | 보통 (실회선 경유) |
| 가격 | 저렴 (IP당) | 비쌈 (트래픽당 과금 많음) |
| 차단 회피력 | 낮음~중간 (대역 식별 쉬움) | 높음 (진짜 사용자처럼 보임) |
| IP 풀 규모 | 중간 | 매우 큼 (수백만) |
| 지역 타게팅 | 제한적 | 정교함 (국가/도시) |
| 적합한 용도 | 관대한 사이트, 가격 모니터링 | 까다로운 사이트, 지역별 데이터 |
핵심 판단 기준은 이렇습니다. 목표 사이트가 봇 탐지에 관대하고 속도·비용이 중요하다면 데이터센터 프록시로 충분합니다. 반면 봇 탐지가 강력하거나 특정 국가에서 보이는 콘텐츠(예: 한국 IP에서만 노출되는 가격)가 필요하다면 주거용 프록시가 정답입니다. 실무에서는 데이터센터로 시작해 차단이 잦아지면 주거용으로 올리는 단계적 전략이 비용 효율적입니다.
참고로 “모바일 프록시”라는 세 번째 유형도 있습니다. 이동통신사(LTE/5G) IP를 사용하며 차단 회피력이 가장 높지만 가격도 가장 비쌉니다. 대부분의 프로젝트에서는 데이터센터와 주거용 두 가지로 충분합니다.
8. 프록시 연동 실전 코드
이제 실제 코드에 프록시를 적용해 봅니다. 대부분의 상용 로테이팅 프록시 공급자는 호스트:포트:아이디:비밀번호 형태의 게이트웨이 정보를 줍니다. 이 하나의 엔드포인트로 요청을 보내면 공급자가 알아서 IP를 회전시킵니다.
requests에 프록시 적용
import requests
# 공급자가 제공한 로테이팅 게이트웨이 (예시 형식)
proxy_user = "USERNAME"
proxy_pass = "PASSWORD"
proxy_host = "p.example-proxy.io"
proxy_port = "80"
proxy_url = f"http://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}"
proxies = {"http": proxy_url, "https": proxy_url}
headers = {"User-Agent": "Mozilla/5.0 ... Chrome/124.0 Safari/537.36"}
resp = requests.get(
"https://httpbin.org/ip", # 현재 나가는 IP 확인용
proxies=proxies,
headers=headers,
timeout=15,
)
print(resp.json()) # 요청마다 다른 IP가 찍히면 로테이션 정상 작동
검증 팁: https://httpbin.org/ip는 요청을 보낸 IP를 그대로 돌려줍니다. 같은 코드를 여러 번 돌렸을 때 매번 다른 IP가 찍히면 로테이션이 제대로 동작하는 것입니다. 이 한 줄 검증을 습관화하면 “프록시가 적용됐다고 생각했는데 사실 내 IP로 나가고 있었다”는 흔한 실수를 막을 수 있습니다.
재시도와 백오프 추가
import time
import requests
def fetch_with_retry(url, proxies, headers, max_retries=3):
for attempt in range(max_retries):
try:
resp = requests.get(url, proxies=proxies,
headers=headers, timeout=15)
if resp.status_code == 429:
wait = 2 ** attempt # 지수 백오프
print(f"429 차단, {wait}초 대기 후 재시도")
time.sleep(wait)
continue
resp.raise_for_status()
return resp
except requests.RequestException as e:
print(f"시도 {attempt+1} 실패: {e}")
time.sleep(2 ** attempt)
return None
로테이팅 프록시를 쓰더라도 429나 일시적 네트워크 오류는 발생합니다. 지수 백오프(exponential backoff)로 재시도하면 일시적 차단을 자연스럽게 넘길 수 있고, 상대 서버에도 부담을 덜 줍니다. 프록시 + 백오프 + 적절한 지연, 이 세 가지가 안정적인 크롤러의 3대 기본기입니다.
Playwright에 프록시 적용
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(
headless=True,
proxy={
"server": "http://p.example-proxy.io:80",
"username": "USERNAME",
"password": "PASSWORD",
},
)
page = browser.new_page(locale="ko-KR")
page.goto("https://httpbin.org/ip")
print(page.inner_text("body")) # 프록시 IP 확인
browser.close()
Playwright는 launch()의 proxy 인자로 간단히 프록시를 붙일 수 있습니다. 동적 페이지를 다루면서 동시에 IP 로테이션이 필요한 까다로운 사이트에서 이 조합이 위력을 발휘합니다. 다만 브라우저 자동화 + 주거용 프록시는 자원과 비용이 모두 크므로, 정말 필요한 경우에만 쓰는 것이 좋습니다.
9. robots.txt · 법적 · 윤리적 준수 (가장 중요)
기술적으로 가능하다고 해서 모두 해도 되는 것은 아닙니다. 이 섹션은 이 글에서 가장 중요한 부분입니다. 합법적이고 윤리적인 스크래핑만이 지속 가능하며, 비즈니스 자산으로서 가치가 있습니다. 한국 상황을 중심으로 핵심 원칙을 정리합니다.
robots.txt 확인은 기본 중의 기본
거의 모든 사이트는 루트에 /robots.txt 파일을 두어 “어떤 경로를 자동 수집해도 되는지”를 명시합니다. 크롤러를 짜기 전에 반드시 확인하고 이를 준수해야 합니다. 파이썬 표준 라이브러리로 간단히 검사할 수 있습니다.
import urllib.robotparser
rp = urllib.robotparser.RobotFileParser()
rp.set_url("https://example.com/robots.txt")
rp.read()
ua = "MyScraperBot"
if rp.can_fetch(ua, "https://example.com/articles"):
print("수집 허용 경로")
else:
print("수집 금지 경로 — 접근하지 않음")
# 크롤 지연(Crawl-delay)이 명시돼 있으면 존중
print("권장 지연:", rp.crawl_delay(ua))
한국에서 반드시 지켜야 할 선
- 이용약관(ToS) 준수: 많은 사이트가 약관에서 자동 수집을 명시적으로 금지합니다. 약관 위반은 민사상 책임으로 이어질 수 있습니다.
- 개인정보보호법: 한국 개인정보보호법(PIPA)은 이름·연락처·주민번호 등 개인을 식별할 수 있는 정보의 수집·이용을 엄격히 규제합니다. 공개된 페이지라도 개인정보를 동의 없이 대량 수집·저장하는 것은 위법 소지가 큽니다.
- 저작권: 기사·이미지·DB 등은 저작권 또는 데이터베이스권의 보호 대상입니다. 수집한 콘텐츠를 그대로 재배포하면 침해가 됩니다.
- 서버 부하 최소화: 과도한 요청으로 상대 서버에 장애를 유발하면, 정보통신망법상 업무방해로 해석될 위험이 있습니다. 반드시 지연과 동시성 제한을 둬야 합니다.
- 공개 API 우선: 사이트가 공식 API를 제공한다면 스크래핑보다 API를 쓰는 것이 합법적이고 안정적입니다.
한 줄로 요약하면, “공개된 비개인 데이터를, robots.txt와 약관이 허용하는 범위에서, 서버에 부담을 주지 않는 속도로, 정당한 목적을 위해” 수집하는 것이 안전한 기준입니다. 개인정보·로그인 뒤 데이터·약관이 금지한 경로는 손대지 않는 것이 원칙입니다. 의심스러우면 수집하지 않거나, 법률 전문가의 조언을 구하는 것이 현명합니다. 이 글은 어디까지나 기술 가이드이며 법률 자문이 아니라는 점을 분명히 합니다.
10. 대규모 운영을 위한 인프라
소규모 수집은 내 노트북에서도 됩니다. 그러나 24시간 돌아가는 안정적인 데이터 파이프라인을 만들려면 별도의 서버와 신뢰할 수 있는 프록시 인프라가 필요합니다. 합법적인 범위에서 데이터 수집 비즈니스를 운영할 때 필요한 두 가지 핵심 요소를 정리합니다.
첫째, 로테이팅 프록시입니다. 위에서 설명했듯 단일 IP로는 규모 있는 수집이 불가능합니다. 둘째, 크롤러를 24시간 돌릴 서버(VPS)입니다. 내 PC를 계속 켜둘 수는 없으니, 클라우드 서버에 크롤러를 올려 스케줄링(cron 등)으로 자동 실행하는 구조가 표준입니다.
대규모 스크래핑에는 로테이팅 프록시가 사실상 필수입니다. 직접 IP를 모으는 것은 비효율적이고 관리 부담이 크기 때문에, 검증된 공급자의 풀을 빌려 쓰는 것이 비용·안정성 면에서 압도적으로 유리합니다.
실전 추천 — 프록시와 서버 조합
로테이팅 프록시 공급자 중 한국 개발자가 시작하기에 가장 부담 없는 곳은 WebShare입니다. 무료 플랜으로 데이터센터 프록시 10개를 바로 받아 위의 코드들을 그대로 테스트해 볼 수 있고, 주거용 프록시도 합리적인 가격에 제공합니다. 가입 직후 게이트웨이 정보가 나오므로, 8장의 httpbin.org/ip 검증 코드로 5분 안에 로테이션 동작을 확인할 수 있습니다. → WebShare 로테이팅 프록시 무료로 시작하기
크롤러를 24시간 안정적으로 돌릴 서버가 필요하다면 DigitalOcean의 가장 저렴한 Droplet(월 4~6달러대)이면 충분합니다. 신규 가입 시 200달러 크레딧이 제공되어 몇 달간 사실상 무료로 파이프라인을 운영하며 검증할 수 있습니다. 우분투 서버에 파이썬과 위 라이브러리를 올리고 cron으로 스케줄링하면 끝입니다. → DigitalOcean VPS에서 스크래퍼 24시간 운영하기
(이 링크는 제휴 링크이며, 가입 시 추가 비용은 없습니다.)
더 많은 개발 도구와 자동화 스택이 궁금하다면 dibi8 개발 도구 디렉터리에서 카테고리별로 정리된 도구들을 살펴보세요. 수집한 데이터를 자동으로 가공·전송하는 워크플로를 만들고 싶다면 n8n 자동화 한국어 가이드와 결합하면 “수집 → 가공 → 알림/저장”까지 완전 자동화된 데이터 파이프라인을 구성할 수 있습니다.
11. 자주 묻는 질문 (FAQ)
Q1. 웹 스크래핑은 불법인가요?
스크래핑 자체가 일률적으로 불법인 것은 아닙니다. 다만 무엇을, 어떻게, 어떤 목적으로 수집하느냐에 따라 합법과 위법이 갈립니다. 공개된 비개인 데이터를 robots.txt와 이용약관이 허용하는 범위에서, 서버에 과부하를 주지 않고 수집하는 것은 일반적으로 허용됩니다. 반면 개인정보를 동의 없이 대량 수집하거나, 약관이 금지한 경로에 접근하거나, 수집물을 무단 재배포하면 법적 문제가 발생할 수 있습니다. 한국에서는 개인정보보호법·저작권법·정보통신망법을 특히 유의해야 합니다.
Q2. 무료 프록시를 써도 되나요?
실무에서는 권장하지 않습니다. 인터넷에 떠도는 공개 무료 프록시는 ① 속도가 매우 느리고, ② 언제 죽을지 모르며, ③ 가장 위험하게는 중간자 공격으로 트래픽(로그인 정보 등)을 가로챌 수 있습니다. 테스트라면 WebShare 같은 공급자의 무료 플랜으로 정식 인프라를 검증하는 편이 훨씬 안전하고 안정적입니다. 신뢰할 수 없는 출처의 무료 프록시로 민감한 요청을 보내는 것은 절대 피하세요.
Q3. 데이터센터와 주거용 중 무엇으로 시작해야 하나요?
대부분 데이터센터 프록시로 시작하는 것이 현명합니다. 가격이 저렴하고 속도가 빨라서, 목표 사이트의 봇 탐지가 관대하다면 이것만으로 충분합니다. 데이터센터로 돌렸을 때 차단이 잦거나, 특정 국가에서만 보이는 콘텐츠가 필요하다면 그때 주거용으로 올리세요. 처음부터 비싼 주거용을 쓰는 것은 대부분 과투자입니다.
Q4. requests로 데이터가 안 보이는데 어떻게 하나요?
페이지가 JavaScript로 콘텐츠를 렌더링하는 동적 페이지일 가능성이 높습니다. 두 가지 방법이 있습니다. ① Playwright로 실제 브라우저를 띄워 렌더링 후 추출하기. ② 브라우저 개발자 도구의 Network 탭에서 페이지가 호출하는 내부 API(XHR/Fetch)를 찾아 그 JSON 엔드포인트를 직접 호출하기. 두 번째 방법이 가능하면 훨씬 빠르고 가볍습니다. 동적 페이지라고 무조건 브라우저 자동화부터 꺼내기보다, 내부 API를 먼저 찾아보는 습관을 들이세요.
Q5. CAPTCHA가 뜨면 어떻게 하나요?
CAPTCHA가 자주 뜬다는 것은 그 사이트가 자동 수집을 강하게 거부한다는 신호입니다. 이는 “기술적으로 어떻게 뚫느냐”보다 “이 데이터를 정말 스크래핑으로 수집해도 되는가”를 먼저 자문해야 하는 지점입니다. 우선 공식 API가 있는지 확인하고, 요청 빈도를 낮추거나 주거용 프록시로 자연스러운 패턴을 만드는 합법적 조정을 시도하세요. 그래도 계속 막힌다면, 그 사이트는 수집 대상에서 제외하는 것이 윤리적으로도 법적으로도 안전한 선택입니다.
마무리 — 안전하고 지속 가능한 스크래핑
지금까지 파이썬 웹 스크래핑의 기초(requests + BeautifulSoup)부터 동적 페이지 처리(Playwright), IP 차단의 원리와 로테이팅 프록시의 작동 방식, 데이터센터와 주거용 프록시의 차이, 실전 연동 코드, 그리고 가장 중요한 합법·윤리 준수까지 한 흐름으로 살펴봤습니다. 기술의 핵심은 명확합니다. 정적이면 requests, 동적이면 Playwright, 규모가 커지면 로테이팅 프록시 + VPS입니다.
그러나 기술보다 더 중요한 것은 자세입니다. robots.txt를 확인하고, 이용약관을 존중하며, 개인정보에 손대지 않고, 상대 서버에 부담을 주지 않는 속도로 수집하는 것 — 이 원칙을 지킬 때만 스크래핑은 “위험한 회색지대 작업”이 아니라 “신뢰할 수 있는 데이터 자산을 만드는 합법적 엔지니어링”이 됩니다. 빠르게 많이 긁는 크롤러가 아니라, 오래 안정적으로 돌면서 문제를 일으키지 않는 크롤러를 만드는 것이 진짜 실력입니다.
이제 직접 만들어 볼 차례입니다. 작은 정적 페이지 하나에서 requests + BeautifulSoup로 시작해, 차단을 만나면 로테이팅 프록시를 붙이고, 24시간 운영이 필요해지면 VPS로 옮기는 — 그 단계적 여정이 곧 데이터 엔지니어로 성장하는 길입니다. 합법적인 범위 안에서, 한 걸음씩 나아가시길 바랍니다.
