중복 파일 삭제 스크립트를 돌렸다가 식은땀 흘린 날

이미지
중복 파일 삭제 스크립트를 돌렸다가 식은땀 흘린 날 이 블로그의 중복 파일 자동 삭제 편 과 파일명 일괄 변경 편 을 보면 공통적으로 "DRY_RUN"이라는 안전장치가 들어 있습니다. 실제 삭제나 변경 전에 미리보기부터 하도록 만든 이 습관은, 사실 처음부터 있던 게 아니라 한 번의 아찔한 경험 뒤에 생긴 것입니다. 당시 상황은 이랬습니다. 다운로드 폴더가 오래 방치되어 있어 용량을 확인해보니 중복 파일이 상당히 많았고, "파일 해시값을 비교해서 중복이면 자동으로 지우는" 스크립트를 처음 짜서 바로 실행했습니다. 사건 발생 — 실행 버튼을 누른 직후 처음 짠 코드는 대략 이런 형태였습니다. import hashlib from pathlib import Path from collections import defaultdict folder = Path(r"C:\Users\내이름\Downloads") hash_map = defaultdict(list) def get_hash(filepath): h = hashlib.md5() with open(filepath, "rb") as f: h.update(f.read()) return h.hexdigest() for file in folder.rglob("*"): if file.is_file(): hash_map[get_hash(file)].append(file) # 중복이면 첫 번째만 남기고 나머지 삭제 for files in hash_map.values(): if len(files) > 1: for f in files[1:]: f.unlink() # ← 바로 삭제 실행 print(f"삭제: {f.name}") 실행하자마자 터미널에 "삭제: ......

requests+BeautifulSoup vs Selenium, 웹 크롤링 뭐가 다를까? 파이썬 비교분석

requests+BeautifulSoup vs Selenium, 웹 크롤링 뭐가 다를까? 파이썬 비교분석

두 가지 파이썬 웹 크롤링 방식을 나란히 비교하는 모습


이 블로그의 웹 데이터 자동 수집 편에서는 requestsBeautifulSoup을 사용했고, 웹사이트 자동 로그인 편에서는 Selenium을 사용했습니다. "둘 다 웹에서 데이터를 가져오는데 왜 다른 도구를 썼을까" 궁금하셨던 분들을 위해, 이번엔 같은 작업을 두 가지 방식으로 각각 구현해보면서 차이를 직접 비교해보겠습니다.


근본적인 차이 — 무엇을 읽어오는가

requests+BeautifulSoup  → 서버가 처음 보내주는 "날것의 HTML"만 읽음
Selenium               → 실제 브라우저를 띄워서 자바스크립트가 실행된 "최종 화면"을 읽음

이 한 줄이 모든 차이의 근원입니다. 요즘 많은 웹사이트는 페이지가 처음 열릴 때는 빈 뼈대만 오고, 자바스크립트가 실행되면서 실제 내용(상품 목록, 가격 등)이 채워지는 방식으로 만들어집니다. requests는 이 자바스크립트를 실행하지 못하기 때문에, 이런 사이트에서는 빈 껍데기만 가져오게 됩니다.


비교 1 — 같은 뉴스 목록 페이지 크롤링하기

정적인 뉴스 목록 페이지(자바스크립트 없이 서버가 완성된 HTML을 바로 보내주는 경우)를 크롤링하는 상황을 가정합니다.

requests + BeautifulSoup

import requests
from bs4 import BeautifulSoup
import time

start = time.time()

res = requests.get("https://example-news.com/list")
soup = BeautifulSoup(res.text, "html.parser")
titles = [t.get_text(strip=True) for t in soup.select(".news-title")]

print(f"수집 완료: {len(titles)}건 / 소요시간: {time.time()-start:.2f}초")

Selenium

from selenium import webdriver
from selenium.webdriver.common.by import By
import time

start = time.time()

driver = webdriver.Chrome()   # 실제 브라우저 창이 뜸
driver.get("https://example-news.com/list")
time.sleep(2)   # 페이지 로딩 대기

elements = driver.find_elements(By.CLASS_NAME, "news-title")
titles = [e.text for e in elements]
driver.quit()

print(f"수집 완료: {len(titles)}건 / 소요시간: {time.time()-start:.2f}초")
💡 체감 속도 차이: 정적인 페이지 기준으로 requests는 보통 0.5초 내외, Selenium은 브라우저를 띄우고 로딩을 기다려야 하므로 3~5초 이상 걸립니다. 같은 작업을 정적 페이지에서 한다면 requests 쪽이 5~10배 이상 빠릅니다.

비교 2 — 스크롤해야 나오는 동적 콘텐츠 가져오기

이번엔 페이지를 아래로 스크롤해야 상품이 추가로 로딩되는(무한 스크롤) 쇼핑몰 페이지를 가정합니다.

requests + BeautifulSoup (한계에 부딪힘)

import requests
from bs4 import BeautifulSoup

res = requests.get("https://example-shop.com/products")
soup = BeautifulSoup(res.text, "html.parser")
products = soup.select(".product-item")

print(f"수집된 상품: {len(products)}개")
# ⚠ 결과: 스크롤 전 처음 로딩된 20개만 수집됨
#   나머지 상품은 자바스크립트로 추가 로딩되기 때문에 requests로는 접근 불가

Selenium (스크롤 동작까지 재현 가능)

from selenium import webdriver
from selenium.webdriver.common.by import By
import time

driver = webdriver.Chrome()
driver.get("https://example-shop.com/products")

# 스크롤을 여러 번 내려서 추가 상품이 로딩되게 함
for _ in range(5):
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
    time.sleep(1.5)

products = driver.find_elements(By.CLASS_NAME, "product-item")
print(f"수집된 상품: {len(products)}개")
# ✔ 결과: 스크롤한 만큼 추가 로딩된 상품까지 모두 수집됨
driver.quit()
💡 여기서 알 수 있는 것: 무한 스크롤, 버튼 클릭 후 나타나는 콘텐츠, 로그인 후에만 보이는 페이지는 requests로는 근본적으로 접근할 수 없습니다. 이 블로그의 웹사이트 자동 로그인 편에서 Selenium을 쓴 이유가 바로 "로그인 버튼 클릭"이라는 상호작용이 필요했기 때문입니다.

비교 3 — 서버 자원 소모와 안정성

                  requests+BeautifulSoup       Selenium
메모리 사용량     매우 적음 (수십 MB)          많음 (수백 MB, 브라우저 구동)
동시 실행         수백 개 요청도 가벼움         브라우저 인스턴스라 5~10개도 부담
서버 차단 위험    User-Agent 위조로 우회 가능   실제 브라우저라 차단 확률 낮음
설치 요구사항     pip install만 하면 끝         크롬 드라이버까지 추가 설치 필요
자바스크립트 실행 ✗ 불가능                     ✓ 완벽 지원
디버깅            텍스트 로그만 확인            브라우저 화면을 눈으로 직접 확인 가능

결론 — 어떤 상황에 뭘 써야 할까

requests + BeautifulSoup을 선택하세요, 만약:
페이지 소스보기(Ctrl+U)로 열었을 때 원하는 데이터가 이미 HTML 안에 텍스트로 보인다면, 별다른 고민 없이 이 조합을 사용하세요. 빠르고 가볍고, 여러 페이지를 대량으로 수집할 때도 서버 부담이 적습니다. 웹 데이터 자동 수집 편, 주식·환율 자동 수집 편이 이 조합으로 충분했던 이유입니다.

Selenium을 선택하세요, 만약:
로그인, 클릭, 스크롤처럼 사람이 직접 조작해야 나타나는 데이터가 필요하거나, 페이지 소스보기에는 없는데 화면에는 보이는 데이터(자바스크립트로 나중에 채워지는 콘텐츠)라면 Selenium이 유일한 선택지입니다. 느리고 무겁지만, 사람이 브라우저로 보는 것과 똑같은 결과를 얻을 수 있습니다.

판단이 어렵다면 이렇게 확인하세요:
크롤링하려는 페이지에서 마우스 오른쪽 클릭 → "페이지 소스 보기"를 열어보세요. 원하는 텍스트가 그 소스 안에 그대로 보인다면 requests로 충분합니다. 소스에는 안 보이는데 실제 화면에는 보인다면 자바스크립트로 렌더링되는 것이므로 Selenium이 필요합니다.


핵심 요약

  • requests+BeautifulSoup: 빠르고 가벼움, 정적 HTML만 접근 가능, 대량 수집에 유리
  • Selenium: 느리고 무겁지만 자바스크립트·로그인·클릭·스크롤까지 재현 가능
  • 판단 기준: "페이지 소스 보기"에 원하는 데이터가 있으면 requests, 없으면 Selenium
  • 실무 팁: 먼저 requests로 시도해보고, 데이터가 안 나오면 그때 Selenium으로 전환하는 순서를 권장

이 블로그의 인기 게시물

느려진 구글 크롬 속도 2배 빨라지는 3가지 설정 방법 (2026년 최신 가이드)

카카오톡 용량 줄이기! 대화방 파일 삭제로 스마트폰 용량 확보법 (1분 해결)

업무 속도 3배 빨라지는 윈도우 기본 캡처 도구 단축키 및 200% 활용 꿀팁