
프로그래밍을 배우다 보면 언젠가 한 번쯤 이런 생각을 하게 됩니다. "저 웹사이트의 데이터를 자동으로 가져올 수 없을까?" 바로 그 순간이 파이썬 웹 크롤링을 시작할 타이밍입니다. 오늘은 입문자도 바로 따라 할 수 있도록 requests 라이브러리와 BeautifulSoup 사용법을 실습 예제 중심으로 차근차근 설명드릴게요.
웹 크롤링이란 프로그램이 웹사이트를 자동으로 방문해 필요한 정보를 수집하는 기술입니다. 뉴스 기사 제목 모으기, 쇼핑몰 가격 비교, 부동산 시세 추적 등 실생활에서 활용도가 매우 높습니다. 파이썬은 강력한 라이브러리 생태계 덕분에 웹 스크래핑을 가장 쉽게 배울 수 있는 언어로 손꼽힙니다.
이 글은 파이썬 크롤링 입문자 가이드로서, 설치부터 실전 예제까지 모두 다룹니다. 코드 한 줄 한 줄을 직접 따라 치면서 읽어보세요. 끝까지 따라오신다면 여러분도 오늘 당장 원하는 데이터를 자동으로 수집할 수 있게 됩니다.
목차

웹 크롤링이란? 파이썬으로 왜 배워야 할까
웹 크롤링(Web Crawling)과 웹 스크래핑(Web Scraping)은 종종 혼용되지만 미묘하게 다릅니다. 크롤링은 웹 전체를 탐색하며 링크를 따라다니는 행위이고, 스크래핑은 특정 페이지에서 원하는 데이터를 추출하는 행위입니다. 실무에서는 두 기술을 함께 사용하는 경우가 많습니다.
파이썬이 웹 스크래핑에 최적화된 이유는 다음과 같습니다.
- 간결한 문법: 적은 코드로 많은 일을 처리할 수 있습니다.
- 풍부한 라이브러리: requests, BeautifulSoup, Selenium, Scrapy 등 검증된 도구가 많습니다.
- 활발한 커뮤니티: 막히는 부분이 있어도 검색하면 금방 해결책을 찾을 수 있습니다.
- 데이터 분석과 연계: pandas, matplotlib 등과 연결해 수집한 데이터를 바로 분석할 수 있습니다.
단, 크롤링을 시작하기 전에 반드시 해당 사이트의 robots.txt 파일과 이용 약관을 확인하세요. 무분별한 크롤링은 서버에 부하를 주거나 법적 문제로 이어질 수 있습니다. 항상 책임감 있는 크롤링을 실천해야 합니다.

환경 설정: requests와 BeautifulSoup 설치하기
본격적인 웹 스크래핑 실습 예제에 앞서 필요한 라이브러리를 설치해야 합니다. 파이썬이 이미 설치되어 있다고 가정하고 진행합니다. 터미널(명령 프롬프트)을 열고 아래 명령어를 입력하세요.
pip install requests
pip install beautifulsoup4
pip install lxml
requests는 HTTP 요청을 보내는 라이브러리입니다. 웹 브라우저가 웹사이트에 접속하듯, 파이썬 코드가 서버에 페이지를 요청할 수 있게 해줍니다. beautifulsoup4는 HTML 문서를 파싱하고 원하는 요소를 쉽게 찾아주는 라이브러리입니다. lxml은 BeautifulSoup이 HTML을 파싱할 때 사용하는 고속 파서입니다.
설치가 완료되었으면 파이썬 파일을 하나 만들어봅시다. 파일 이름은 crawler.py로 하겠습니다. 이제 본격적으로 코드를 작성할 준비가 되었습니다.

requests 라이브러리 기초: HTTP 요청 보내기
requests 라이브러리의 핵심은 단순함에 있습니다. 복잡한 HTTP 통신을 단 몇 줄로 처리할 수 있습니다. 가장 기본적인 GET 요청부터 시작해봅시다.
import requests
# 웹 페이지에 GET 요청 보내기
url = "https://books.toscrape.com/"
response = requests.get(url)
# 상태 코드 확인
print(response.status_code) # 200이면 성공
print(response.encoding) # 인코딩 확인
print(response.text[:500]) # HTML 첫 500자 출력
status_code가 200이라면 요청이 성공한 것입니다. 404는 페이지를 찾을 수 없다는 뜻이고, 403은 접근이 거부되었다는 의미입니다. response.text에는 해당 페이지의 전체 HTML이 문자열로 담겨 있습니다.
실제 크롤링을 할 때는 헤더(Header)를 설정해 브라우저처럼 보이게 하는 것이 좋습니다. 일부 사이트는 파이썬 requests의 기본 User-Agent를 차단하기도 하기 때문입니다.
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/120.0.0.0 Safari/537.36"
}
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status() # 에러 발생 시 예외 처리
timeout=10은 10초 안에 응답이 없으면 에러를 발생시키는 옵션입니다. raise_for_status()는 4xx, 5xx 오류 코드일 때 자동으로 예외를 발생시켜 에러를 놓치지 않게 해줍니다. 이 두 가지는 실무에서 반드시 습관화해야 할 패턴입니다.

BeautifulSoup 사용법: HTML 파싱과 데이터 추출
requests로 HTML을 가져왔다면, 이제 BeautifulSoup으로 원하는 데이터를 뽑아낼 차례입니다. BeautifulSoup은 HTML 트리 구조를 파이썬 객체로 변환해 직관적인 방법으로 요소를 탐색할 수 있게 해줍니다.
from bs4 import BeautifulSoup
# HTML 파싱
soup = BeautifulSoup(response.text, "lxml")
# 제목 태그 찾기
title = soup.find("title")
print(title.text)
# 모든 h1 태그 찾기
h1_tags = soup.find_all("h1")
for tag in h1_tags:
print(tag.text.strip())
BeautifulSoup의 핵심 메서드는 두 가지입니다.
- find(태그명): 조건에 맞는 첫 번째 요소를 반환합니다.
- find_all(태그명): 조건에 맞는 모든 요소를 리스트로 반환합니다.
CSS 선택자를 활용하면 더 정밀하게 요소를 찾을 수 있습니다.
# CSS 선택자 사용
# 클래스명으로 찾기
items = soup.select(".product_pod")
# 특정 태그의 특정 클래스 찾기
prices = soup.select("p.price_color")
# 속성으로 찾기
links = soup.find_all("a", href=True)
for link in links:
print(link["href"]) # href 속성값 출력
select()는 CSS 선택자 문법을 그대로 사용할 수 있어 프론트엔드 개발 경험이 있다면 훨씬 친숙하게 느껴질 것입니다. 태그의 속성값은 딕셔너리처럼 접근할 수 있습니다. link["href"]와 같은 방식으로 원하는 속성을 추출하면 됩니다.

실전 웹 스크래핑 실습 예제: 도서 정보 수집하기
이제 이론을 넘어 실제로 동작하는 웹 스크래핑 실습 예제를 만들어봅시다. books.toscrape.com은 크롤링 연습용으로 만들어진 합법적인 사이트입니다. 이 사이트에서 책 제목, 가격, 평점을 수집해보겠습니다.
import requests
from bs4 import BeautifulSoup
import csv
import time
def crawl_books(base_url, max_pages=3):
"""도서 정보를 여러 페이지에서 수집하는 함수"""
all_books = []
for page in range(1, max_pages + 1):
if page == 1:
url = base_url
else:
url = f"{base_url}catalogue/page-{page}.html"
headers = {
"User-Agent": "Mozilla/5.0 (compatible; MyBot/1.0)"
}
try:
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status()
except requests.RequestException as e:
print(f"페이지 {page} 요청 실패: {e}")
continue
soup = BeautifulSoup(response.text, "lxml")
books = soup.select("article.product_pod")
for book in books:
# 제목 추출
title = book.select_one("h3 a")["title"]
# 가격 추출
price = book.select_one("p.price_color").text.strip()
# 평점 추출 (클래스명에서 추출)
rating_class = book.select_one("p.star-rating")["class"]
rating = rating_class[1] # One, Two, Three, Four, Five
all_books.append({
"제목": title,
"가격": price,
"평점": rating
})
print(f"페이지 {page} 완료: {len(books)}권 수집")
time.sleep(1) # 서버 부하 방지를 위한 딜레이
return all_books
# 실행
base_url = "https://books.toscrape.com/"
books = crawl_books(base_url, max_pages=3)
# CSV 저장
with open("books.csv", "w", newline="", encoding="utf-8-sig") as f:
fieldnames = ["제목", "가격", "평점"]
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(books)
print(f"\n총 {len(books)}권의 정보를 books.csv에 저장했습니다.")
이 코드에서 주목할 부분이 몇 가지 있습니다.
- time.sleep(1): 요청 사이에 1초 딜레이를 줍니다. 서버에 과도한 부하를 주지 않기 위한 배려이자 차단을 피하는 방법입니다.
- try-except 블록: 네트워크 에러가 발생해도 프로그램이 멈추지 않고 다음 페이지로 계속 진행합니다.
- utf-8-sig 인코딩: 엑셀에서 한글이 깨지지 않도록 BOM(Byte Order Mark)이 포함된 UTF-8을 사용합니다.
코드를 실행하면 현재 폴더에 books.csv 파일이 생성되고, 총 60권(3페이지 × 20권)의 도서 정보가 저장됩니다. 엑셀로 열어서 데이터를 확인해보세요.

파이썬 크롤링 입문자가 자주 만나는 문제와 해결책
파이썬 웹 크롤링을 처음 배울 때 자주 마주치는 문제들을 미리 알고 있으면 훨씬 수월하게 진행할 수 있습니다. 대표적인 문제와 해결 방법을 정리했습니다.
1. 403 Forbidden 에러
서버가 크롤러 접근을 차단한 경우입니다. User-Agent 헤더를 브라우저처럼 설정하면 대부분 해결됩니다. 그래도 안 된다면 requests.Session()을 사용해 쿠키를 유지하거나, 요청 간격을 늘려보세요.
2. 한글 인코딩 깨짐
response.encoding을 확인하고 직접 설정해보세요.
response.encoding = "utf-8" # 또는 "euc-kr"
print(response.text)
3. 원하는 요소를 찾지 못하는 경우
브라우저 개발자 도구(F12)로 정확한 HTML 구조를 확인하세요. 동적으로 렌더링되는 콘텐츠라면 requests로는 가져올 수 없습니다. 이 경우 Selenium이나 Playwright를 사용해야 합니다.
4. 과도한 요청으로 IP 차단
time.sleep()으로 요청 간격을 조절하세요. 대규모 크롤링이 필요하다면 프록시 서버를 활용하는 방법도 있습니다.
5. SSL 인증서 에러
response = requests.get(url, verify=False) # 임시 해결책
# 경고: 보안상 권장하지 않음, 개발 환경에서만 사용

크롤링 심화: 페이지네이션과 데이터 정제
실제 프로젝트에서는 단일 페이지가 아닌 여러 페이지를 순회하고, 수집한 데이터를 정제하는 과정이 필요합니다. 다음 패턴을 익혀두면 대부분의 크롤링 상황에 대응할 수 있습니다.
다음 페이지 링크 자동 추출:
def get_next_page(soup, base_url):
"""다음 페이지 URL을 추출하는 함수"""
next_btn = soup.select_one("li.next a")
if next_btn:
next_href = next_btn["href"]
return f"{base_url}catalogue/{next_href}"
return None # 마지막 페이지면 None 반환
# 사용 예시
current_url = base_url
while current_url:
response = requests.get(current_url, headers=headers)
soup = BeautifulSoup(response.text, "lxml")
# 데이터 추출 로직
# ...
current_url = get_next_page(soup, base_url)
time.sleep(1)
텍스트 데이터 정제:
import re
def clean_price(price_str):
"""가격 문자열에서 숫자만 추출"""
numbers = re.findall(r"\d+\.?\d*", price_str)
return float(numbers[0]) if numbers else 0.0
def clean_text(text):
"""공백 및 특수문자 정리"""
return " ".join(text.split())
# 적용 예시
raw_price = "£51.77"
clean_price_value = clean_price(raw_price) # 51.77
데이터를 수집하는 것만큼 데이터를 정제하고 구조화하는 것도 중요합니다. 실무에서는 수집한 데이터를 pandas DataFrame으로 변환해 분석하거나, SQLite 데이터베이스에 저장해 체계적으로 관리하는 경우가 많습니다.
자주 묻는 질문
파이썬 웹 크롤링은 불법인가요?
크롤링 자체는 불법이 아닙니다. 다만 사이트의 이용약관 위반, 저작권 침해, 개인정보 무단 수집, 서버 과부하 유발 등은 법적 문제가 될 수 있습니다. 반드시 해당 사이트의 robots.txt와 이용약관을 확인하고, 공개된 데이터만 수집하며, 서버에 부하를 주지 않는 방식으로 사용해야 합니다.
requests와 BeautifulSoup으로 모든 사이트를 크롤링할 수 있나요?
JavaScript로 동적으로 렌더링되는 사이트(React, Vue, Angular 등으로 만든 SPA)는 requests만으로는 데이터를 가져올 수 없습니다. 이런 경우에는 Selenium이나 Playwright 같은 브라우저 자동화 도구를 사용해야 합니다. 페이지 소스 보기(Ctrl+U)로 원하는 데이터가 HTML에 직접 있는지 확인해보세요.
크롤링 속도를 높이려면 어떻게 해야 하나요?
비동기 처리를 활용하면 크롤링 속도를 크게 높일 수 있습니다. aiohttp와 asyncio를 조합하거나, concurrent.futures의 ThreadPoolExecutor를 사용해 여러 페이지를 동시에 요청할 수 있습니다. 단, 빠른 크롤링은 서버에 부하를 줄 수 있으므로 적절한 딜레이와 동시 요청 수 제한이 필요합니다.
BeautifulSoup에서 find()와 select()의 차이는 무엇인가요?
find() / find_all()은 BeautifulSoup 고유의 메서드로 태그명, 속성, 텍스트 등으로 검색합니다. select() / select_one()은 CSS 선택자 문법을 사용합니다. 복잡한 조건으로 요소를 찾을 때는 CSS 선택자가 더 간결하고, 간단한 태그 검색에는 find()가 직관적입니다. 두 방식을 상황에 맞게 혼용하는 것이 좋습니다.
수집한 데이터를 데이터베이스에 저장할 수 있나요?
물론입니다. 파이썬에서는 SQLite(sqlite3 모듈, 별도 설치 불필요), MySQL(pymysql), PostgreSQL(psycopg2) 등 다양한 데이터베이스에 데이터를 저장할 수 있습니다. 소규모 프로젝트라면 CSV나 SQLite로 시작하고, 데이터가 많아지면 본격적인 RDBMS나 MongoDB 같은 NoSQL 데이터베이스로 이전하는 것을 권장합니다.

마무리: 파이썬 크롤링, 오늘 바로 시작하세요
오늘 우리는 파이썬 웹 크롤링의 기초부터 실전 예제까지 함께 살펴봤습니다. requests 라이브러리로 웹 페이지를 요청하고, BeautifulSoup 사용법으로 원하는 데이터를 추출하는 전체 흐름을 익혔습니다. 여기서 멈추지 마세요.
다음 단계로 도전해볼 만한 주제를 추천드립니다.
- Scrapy 프레임워크: 대규모 크롤링에 최적화된 전문 도구입니다.
- Selenium / Playwright: JavaScript 렌더링 사이트 크롤링에 필수입니다.
- pandas와 결합: 수집한 데이터를 분석하고 시각화해보세요.
- 스케줄링: schedule 라이브러리나 cron으로 정기적으로 데이터를 수집하는 파이프라인을 만들어보세요.
이 파이썬 크롤링 입문자 가이드가 여러분의 첫걸음에 도움이 되었으면 합니다. 직접 코드를 실행해보고, 궁금한 점이 있다면 댓글로 남겨주세요. 함께 공부하면 더 빨리 성장할 수 있습니다. 파이썬으로 무궁무진한 데이터의 세계를 탐험해보세요!
댓글