Beautiful Soup vs Selenium vs Scrapy

Duckhee·2025년 12월 28일
post-thumbnail

Python 웹 스크래핑 도구 정리 - Beautiful Soup vs Selenium vs Scrapy

웹에서 데이터를 긁어올 일이 생겨서 여러 도구들을 공부하면서 정리한 내용

Scraping과 Crawling의 차이

처음엔 나도 같은거 아닌가 했는데 찾아보니 좀 다르다.

Scraping: 특정 웹사이트에서 내가 원하는 데이터만 쏙쏙 뽑아오는 것

  • 예를 들면 쿠팡에서 노트북 가격정보만 가져온다던가

Crawling: 웹사이트를 돌아다니면서 링크를 따라가고 URL을 수집하는 것

  • 구글 검색엔진이 하는 게 이것

실제로는 둘 다 섞어쓰는 경우가 많다.


Beautiful Soup

제일 먼저 배운 도구인데 간단한 작업에는 이게 제일 편하다.

import requests
from bs4 import BeautifulSoup

url = "https://example.com"
response = requests.get(url)
soup = BeautifulSoup(response.text, 'html.parser')

# 이런식으로 태그를 찾아서 데이터를 추출
titles = soup.find_all('h2', class_='title')
for title in titles:
    print(title.text.strip())

특징

  • HTML 파싱만 해주는 라이브러리
  • requests로 HTML을 받아온 다음에 BeautifulSoup으로 파싱하는 구조
  • 정적인 페이지(그냥 HTML만 있는 것)에만 사용 가능

장점

  • 진짜 배우기 쉽다. 튜토리얼 하나만 보면 바로 쓸 수 있다
  • 가볍고 빠르다
  • 간단한 작업에 딱이다

단점

  • JavaScript로 동적으로 로딩되는 것을 못가져온다
    • 요즘 사이트들은 대부분 React, Vue 같은 걸 써서 문제
  • 로그인이나 버튼 클릭 같은 것이 안된다
  • 많은 페이지를 크롤링하려면 직접 반복문을 다 짜야 한다

실제로 써보니 네이버 뉴스 같은 정적 페이지는 잘 되는데, 인스타나 유튜브 댓글 같은 것은 안된다.


Selenium

JavaScript로 렌더링되는 페이지를 크롤링해야 해서 찾아본 게 Selenium

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

options = webdriver.ChromeOptions()
options.add_argument('--headless')  # 브라우저 안띄우고 백그라운드 실행
driver = webdriver.Chrome(options=options)

driver.get("https://example.com")

# JavaScript 로딩을 기다린다 (이거 안하면 에러남)
wait = WebDriverWait(driver, 10)
element = wait.until(EC.presence_of_element_located((By.CLASS_NAME, "content")))

# 데이터 뽑기
items = driver.find_elements(By.CSS_SELECTOR, ".item")
for item in items:
    print(item.text)

driver.quit()  # 이거 꼭 해줘야 한다. 안그러면 크롬 프로세스가 계속 살아있다

특징

  • 실제 브라우저를 켜서 사람이 하는 것처럼 동작
  • 그래서 JavaScript로 만들어진 동적 콘텐츠도 다 가져올 수 있다
  • 버튼 클릭, 스크롤, 로그인 등이 다 가능

장점

  • 요즘 웹사이트들(SPA)을 크롤링할 수 있다
  • 사람이 브라우저를 쓰는 것과 똑같이 동작
  • 디버깅하기 쉽다 (실제로 브라우저를 띄워놓고 뭐가 문제인지 볼 수 있다)

단점

  • 개느리다. 진짜 답답할 정도로 느리다
    • 실제 브라우저를 켜야 되니까 당연
  • 메모리를 엄청 먹는다
  • headless 모드 설정이 생각보다 귀찮다
    • 특히 서버에서 돌릴 때 chromedriver를 설치하고 설정하는 게 번거롭다

삽질했던 것:

# 이렇게 바로 데이터를 가져오면 안된다
driver.get(url)
data = driver.find_element(By.CLASS_NAME, "content").text  # 에러남

# JavaScript 로딩을 기다려야 한다
wait = WebDriverWait(driver, 10)
element = wait.until(EC.presence_of_element_located((By.CLASS_NAME, "content")))
data = element.text  # 이제 된다

처음에 이거 몰라서 한참 헤맸다.

속도 개선

멀티프로세싱으로 여러 브라우저를 동시에 띄우면 좀 나아진다.

from multiprocessing import Pool

def crawl(url):
    driver = webdriver.Chrome(options=options)
    # 크롤링 로직
    driver.quit()
    return data

urls = ['url1', 'url2', 'url3']
with Pool(3) as p:  # 3개 동시 실행
    results = p.map(crawl, urls)

근데 메모리 문제는 여전하다.


Scrapy

큰 프로젝트를 하면서 Selenium이 너무 느려서 찾아본 게 Scrapy

import scrapy

class MySpider(scrapy.Spider):
    name = 'example'
    start_urls = ['https://example.com']
    
    def parse(self, response):
        # XPath를 쓸 수 있다 (CSS selector보다 강력)
        for item in response.xpath('//div[@class="item"]'):
            yield {
                'title': item.xpath('.//h2/text()').get(),
                'price': item.xpath('.//span[@class="price"]/text()').get(),
            }
        
        # 다음 페이지를 자동으로 따라감
        next_page = response.xpath('//a[@class="next"]/@href').get()
        if next_page:
            yield response.follow(next_page, self.parse)

실행은 터미널에서

scrapy crawl example -o result.json

특징

  • 완전한 크롤링 프레임워크 (Beautiful Soup이나 Selenium은 그냥 라이브러리)
  • 비동기 처리로 병렬 크롤링을 지원
  • 설정만 바꿔주면 속도 조절, robots.txt 준수 같은 걸 알아서 해준다

장점

  • 속도가 빠르다. Beautiful Soup보다 훨씬 빠르다
  • 수백~수천 페이지를 크롤링할 때 진짜 좋다
  • Item Pipeline으로 데이터 전처리를 자동화할 수 있다
  # pipelines.py
  class CleanPipeline:
      def process_item(self, item, spider):
          item['price'] = item['price'].replace('원', '').replace(',', '')
          return item
  • 중복 URL을 자동으로 걸러준다
  • 미들웨어로 User-Agent 바꾸기, 프록시 설정 같은 것을 쉽게 할 수 있다

단점

  • 학습곡선이 가파르다. 처음엔 진짜 뭔소린지 모르겠다
    • Spider, Item, Pipeline, Settings... 개념이 많다
  • 간단한 것을 하려고 해도 프로젝트 구조를 다 만들어야 한다
  scrapy startproject myproject

이러면 폴더가 우르르 생긴다

  • JavaScript 렌더링은 기본적으로 안된다
    • Splash 플러그인을 설치해야 하는데 이것도 복잡
  • 플러그인 호환성 문제가 가끔 있다

그래도 BeautifulSoup과 같이 쓸 수 있다:

def parse(self, response):
    soup = BeautifulSoup(response.text, 'html.parser')
    # BeautifulSoup 문법 사용 가능

언제 뭘 쓸까?

내가 경험해보니까

Beautiful Soup

  • 간단한 블로그 글 크롤링
  • 정적 HTML 페이지
  • 빠르게 프로토타입 만들 때
  • 처음 배울 때

실제 썼던 것: 네이버 블로그 포스팅 제목 수집

Selenium

  • 로그인 필요한 사이트
  • 무한스크롤 페이지
  • JavaScript로 동적 로딩되는 사이트
  • 버튼 클릭하거나 폼 입력해야 할 때

실제 썼던 것: 인스타그램 해시태그 검색 결과, 쿠팡 상품 리뷰

Scrapy

  • 수백개 이상의 페이지 크롤링
  • 정기적으로 돌릴 크롤러 만들 때
  • 여러 사이트를 체계적으로 수집
  • 데이터 파이프라인 구축

실제 썼던 것: 부동산 매물 정보 수집 (수천개 페이지)


비교표

Beautiful SoupSeleniumScrapy
난이도쉬움보통어려움
속도빠름느림빠름
JS 렌더링XO△ (플러그인)
대규모 크롤링비추비추추천
배우는 시간1-2시간하루1주일

요즘 추세

Selenium 대신 Playwright를 많이 쓰는 추세

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page()
    page.goto('https://example.com')
    content = page.content()
    browser.close()

Selenium보다 빠르고 API도 더 깔끔하다. 근데 아직 자료는 Selenium이 더 많다.


실전 팁

robots.txt 확인

대부분의 사이트에 https://example.com/robots.txt로 가면 크롤링 규칙이 나와있다

User-agent: *
Disallow: /admin/

이런식으로. 지켜주는 게 좋다.

User-Agent 설정

안하면 차단당할 수 있다

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
response = requests.get(url, headers=headers)

요청 간격

너무 빠르게 요청하면 서버 부담 + IP 차단된다

import time
time.sleep(1)  # 1초 쉬기

에러 처리

try:
    response = requests.get(url, timeout=10)
    response.raise_for_status()
except requests.exceptions.RequestException as e:
    print(f"에러 발생: {e}")
    # 로깅하거나 재시도 로직

실제 프로젝트에서

보통 여러 개를 조합해서 사용한다

  • 메인 크롤링은 Scrapy
  • JavaScript 많은 페이지만 Selenium
  • 간단한 파싱은 Beautiful Soup

무조건 한 도구만 쓸 필요는 없다.


마무리

처음엔 Beautiful Soup으로 시작해서 필요할 때마다 다른 것을 배우는 게 낫다.

웹 스크래핑은 결국 상황에 맞는 도구를 선택하는 게 중요하다. 간단한 작업에는 Beautiful Soup, 동적 페이지에는 Selenium이나 Playwright, 대규모 프로젝트에는 Scrapy를 쓰면 된다.


참고 자료

profile
🌈 I Love DE🌈

0개의 댓글