본문 바로가기
Python

웹 스크래핑 - 인터넷에서 데이터 수집하기

by 샤나엘 2026. 2. 23.
반응형

웹 스크래핑 - 인터넷에서 데이터 수집하기

웹 스크래핑 - 인터넷에서 데이터 수집하기

웹에는 무한한 데이터가 있습니다. 파이썬으로 원하는 정보를 자동으로 수집하는 방법을 배워봅시다.


웹 스크래핑이란?

웹 스크래핑(Web Scraping)은 웹 페이지에서 데이터를 자동으로 추출하는 기술입니다.

사람이 브라우저에서 복사-붙여넣기 하는 작업을, 프로그램이 대신 해주는 것이죠.

활용 예시:

  • 뉴스 헤드라인 수집
  • 상품 가격 비교
  • 날씨 정보 가져오기
  • 부동산 매물 모니터링

필요한 라이브러리 설치

pip install requests beautifulsoup4
라이브러리 역할
requests 웹 페이지를 가져옴 (HTTP 요청)
BeautifulSoup HTML을 파싱하여 원하는 데이터 추출

웹 스크래핑의 흐름

웹 스크래핑 흐름도

3단계로 이루어집니다:

  1. 요청(Request): requests로 웹 페이지 가져오기
  2. 파싱(Parse): BeautifulSoup으로 HTML 분석
  3. 추출(Extract): 원하는 데이터만 골라내기

1단계: 웹 페이지 가져오기

import requests

# 웹 페이지 요청
url = "https://example.com"
response = requests.get(url)

# 상태 코드 확인
print(response.status_code)  # 200이면 성공

# HTML 내용 보기
print(response.text[:200])  # 앞부분 200자만

주요 상태 코드

코드 의미 설명
200 OK 성공적으로 가져옴
403 Forbidden 접근 권한 없음
404 Not Found 페이지가 존재하지 않음
500 Server Error 서버 내부 오류

2단계: HTML 파싱하기

from bs4 import BeautifulSoup

html = """
<html>
<body>
  <h1>오늘의 뉴스</h1>
  <ul>
    <li class="news">파이썬 4.0 출시 예정</li>
    <li class="news">AI 기술 발전 가속화</li>
    <li class="ad">광고: 코딩 부트캠프</li>
  </ul>
</body>
</html>
"""

soup = BeautifulSoup(html, "html.parser")

주요 검색 메서드

# 태그로 찾기
title = soup.find("h1")
print(title.text)  # "오늘의 뉴스"

# 클래스로 찾기
news_list = soup.find_all("li", class_="news")
for news in news_list:
    print(news.text)
# 파이썬 4.0 출시 예정
# AI 기술 발전 가속화

# CSS 선택자로 찾기
items = soup.select("ul li.news")
for item in items:
    print(item.text)
메서드 설명 반환값
find() 첫 번째 일치 요소 검색 태그 객체 1개
find_all() 모든 일치 요소 검색 리스트
select() CSS 선택자로 검색 리스트
select_one() CSS 선택자로 첫 번째만 태그 객체 1개

3단계: 데이터 추출하기

# 텍스트 가져오기
tag = soup.find("h1")
print(tag.text)        # "오늘의 뉴스"
print(tag.get_text())  # 같은 결과

# 속성 가져오기
html2 = '<a href="https://python.org" class="link">파이썬 공식</a>'
soup2 = BeautifulSoup(html2, "html.parser")
link = soup2.find("a")

print(link["href"])     # "https://python.org"
print(link["class"])    # ["link"]
print(link.get("href")) # "https://python.org" (없으면 None)

실전 예제: 명언 수집하기

import requests
from bs4 import BeautifulSoup

# 1. 웹 페이지 가져오기
url = "https://quotes.toscrape.com/"
response = requests.get(url)

# 2. HTML 파싱
soup = BeautifulSoup(response.text, "html.parser")

# 3. 명언 추출
quotes = soup.find_all("div", class_="quote")

for i, quote in enumerate(quotes, 1):
    text = quote.find("span", class_="text").text
    author = quote.find("small", class_="author").text
    print(f"{i}. {text}")
    print(f"   - {author}")
    print()

실행 결과:

1. "The world as we have created it is a process of our thinking..."
   - Albert Einstein

2. "It is our choices, Harry, that show what we truly are..."
   - J.K. Rowling
...

여러 페이지 스크래핑

import requests
from bs4 import BeautifulSoup
import time

all_quotes = []

for page in range(1, 4):  # 1~3페이지
    url = f"https://quotes.toscrape.com/page/{page}/"
    response = requests.get(url)
    soup = BeautifulSoup(response.text, "html.parser")

    quotes = soup.find_all("div", class_="quote")
    for quote in quotes:
        text = quote.find("span", class_="text").text
        author = quote.find("small", class_="author").text
        all_quotes.append({"text": text, "author": author})

    time.sleep(1)  # 서버 부담 줄이기 (예의!)

print(f"총 {len(all_quotes)}개 명언 수집 완료!")

중요: time.sleep()으로 요청 간격을 두는 건 서버에 대한 예의이자 차단 방지 방법입니다.


수집한 데이터 저장하기

CSV로 저장

import csv

with open("quotes.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=["text", "author"])
    writer.writeheader()
    writer.writerows(all_quotes)

print("CSV 파일 저장 완료!")

JSON으로 저장

import json

with open("quotes.json", "w", encoding="utf-8") as f:
    json.dump(all_quotes, f, ensure_ascii=False, indent=2)

print("JSON 파일 저장 완료!")

웹 스크래핑 시 주의사항

항목 설명
robots.txt 확인 사이트/robots.txt에서 크롤링 허용 범위 확인
요청 간격 지키기 time.sleep()으로 서버에 부담 주지 않기
저작권 존중 수집한 데이터의 상업적 사용 주의
이용약관 확인 사이트 이용약관에서 스크래핑 금지 여부 확인

직접 해보기

문제 1: HTML에서 제목 추출

아래 HTML에서 모든 <h2> 태그의 텍스트를 추출하세요.

html = """
<div>
  <h2>첫 번째 장</h2>
  <p>내용...</p>
  <h2>두 번째 장</h2>
  <p>내용...</p>
  <h2>세 번째 장</h2>
  <p>내용...</p>
</div>
"""
정답 보기
from bs4 import BeautifulSoup

html = """
<div>
<h2>첫 번째 장</h2>
<p>내용...</p>
<h2>두 번째 장</h2>
<p>내용...</p>
<h2>세 번째 장</h2>
<p>내용...</p>
</div>
"""

soup = BeautifulSoup(html, "html.parser")
titles = soup.find_all("h2")

for i, title in enumerate(titles, 1):
print(f"{i}. {title.text}")

# 출력:
# 1. 첫 번째 장
# 2. 두 번째 장
# 3. 세 번째 장

문제 2: 링크 수집기

아래 HTML에서 모든 링크의 텍스트와 URL을 추출하세요.

html = """
<nav>
  <a href="https://google.com">구글</a>
  <a href="https://python.org">파이썬</a>
  <a href="https://github.com">깃허브</a>
</nav>
"""
정답 보기
from bs4 import BeautifulSoup

html = """
<nav>
<a href="https://google.com">구글</a>
<a href="https://python.org">파이썬</a>
<a href="https://github.com">깃허브</a>
</nav>
"""

soup = BeautifulSoup(html, "html.parser")
links = soup.find_all("a")

for link in links:
name = link.text
url = link["href"]
print(f"{name}: {url}")

# 출력:
# 구글: https://google.com
# 파이썬: https://python.org
# 깃허브: https://github.com

문제 3: 테이블 데이터 추출

아래 HTML 테이블에서 데이터를 딕셔너리 리스트로 변환하세요.

html = """
<table>
  <tr><th>이름</th><th>점수</th></tr>
  <tr><td>김철수</td><td>95</td></tr>
  <tr><td>이영희</td><td>88</td></tr>
  <tr><td>박민수</td><td>92</td></tr>
</table>
"""
정답 보기
from bs4 import BeautifulSoup

html = """
<table>
<tr><th>이름</th><th>점수</th></tr>
<tr><td>김철수</td><td>95</td></tr>
<tr><td>이영희</td><td>88</td></tr>
<tr><td>박민수</td><td>92</td></tr>
</table>
"""

soup = BeautifulSoup(html, "html.parser")
rows = soup.find_all("tr")[1:] # 헤더 제외

students = []
for row in rows:
cols = row.find_all("td")
students.append({
"이름": cols[0].text,
"점수": int(cols[1].text)
})

print(students)
# [{'이름': '김철수', '점수': 95}, {'이름': '이영희', '점수': 88}, {'이름': '박민수', '점수': 92}]


오늘의 정리

개념 설명
requests.get() 웹 페이지 HTML을 가져옴
BeautifulSoup() HTML을 파싱 가능한 객체로 변환
find() / find_all() 태그, 클래스 등으로 요소 검색
select() CSS 선택자로 요소 검색
.text / ["attr"] 텍스트 또는 속성 값 추출
time.sleep() 요청 간격을 두어 서버 배려

다음 편 예고

다음 편에서는 API 활용하기를 다룹니다. 스크래핑보다 깔끔하게 데이터를 가져오는 공식적인 방법, REST API를 배워봅시다!


파이썬 Python 파이썬독학 웹스크래핑 크롤링 requests BeautifulSoup 데이터수집 파이썬실전 IT교육

반응형

댓글