Search for a command to run...

안녕하세요, 데이터에 목마른 개발자 여러분! 오늘은 파이썬을 이용해 웹에 흩어져 있는 방대한 데이터를 수집하는 기술, 바로 **웹 스크래핑(Web Scraping)**에 대해 알아보겠습니다. 이 글 하나로 정적 웹사이트는 물론, 동적 웹사이트까지 자유자재로 크롤링하고 원하는 정보를 추출하는 방법을 익히실 수 있을 겁니다. 핵심 도구는 바로 BeautifulSoup과 Selenium입니다!
웹 스크래핑은 간단히 말해, 웹사이트에서 자동화된 방식으로 데이터를 추출하는 기술을 의미합니다. 주식 시세, 부동산 매물 정보, 뉴스 기사, 상품 가격 등 웹에 공개된 거의 모든 데이터를 수집하여 분석하거나 다른 용도로 활용할 수 있게 해주죠. 마치 데이터의 바다에서 원하는 물고기만 콕 집어 낚아 올리는 것과 같습니다.
requests와 BeautifulSoup가장 기본적인 웹 스크래핑은 정적인 HTML 페이지에서 정보를 가져오는 것입니다. 이때는 requests 라이브러리로 HTML 코드를 가져오고, BeautifulSoup으로 파싱(parsing)하여 원하는 정보를 손쉽게 추출할 수 있습니다.
먼저, 라이브러리를 설치해 볼까요?
pip install requests
pip install beautifulsoup4
pip install lxml # 파싱을 위한 파서
이제 간단한 예제를 통해 네이버 뉴스 제목을 가져와 보겠습니다.
import requests
from bs4 import BeautifulSoup
# 1. 타겟 URL로 HTTP GET 요청 보내기
url = '[https://news.naver.com/](https://news.naver.com/)'
response = requests.get(url)
# 2. BeautifulSoup으로 HTML 파싱하기
if response.status_code == 200:
html = response.text
soup = BeautifulSoup(html, 'lxml')
# 3. 원하는 요소(element) 찾기
# 예: 주요 뉴스 헤드라인 (클래스명은 실제 웹사이트 구조에 따라 달라질 수 있습니다)
headline_links = soup.select('.hdline_article_tit > a') # CSS 선택자(selector) 사용
print("--- 네이버 뉴스 헤드라인 ---")
for i, link in enumerate(headline_links):
# 공백 및 줄바꿈 제거 후 출력
title = link.get_text(strip=True)
href = link.get('href')
print(f"{i+1}. {title}")
print(f" - 링크: {href}")
else:
print(f"HTTP 요청 실패: {response.status_code}")
soup.select() 메서드에 CSS 선택자를 사용하면 jQuery처럼 매우 직관적으로 원하는 태그를 선택할 수 있습니다. 정말 간단하죠?
Selenium의 등장하지만 최근의 웹사이트들은 JavaScript를 통해 동적으로 콘텐츠를 생성하는 경우가 많습니다. requests는 초기 HTML 소스만 가져오기 때문에, JavaScript가 실행된 후의 최종 모습을 보지 못합니다. 이 문제를 해결해 주는 것이 바로 *헤드리스 브라우저(Headless Browser)*를 제어하는 Selenium입니다.
Selenium은 원래 웹 애플리케이션 테스트를 위한 도구지만, 웹 브라우저 자체를 코드로 제어할 수 있다는 점 때문에 강력한 웹 스크래핑 도구로도 사용됩니다. 사용자가 버튼을 클릭하고, 글자를 입력하고, 스크롤하는 모든 행위를 코드로 구현할 수 있죠.
Selenium을 사용하려면 WebDriver라는 것이 필요합니다. 여러분이 사용하는 브라우저(Chrome, Firefox 등)에 맞는 WebDriver를 다운로드해야 합니다.
pip install selenium
이번에는 JavaScript로 렌더링되는 쇼핑몰의 상품 정보를 가져오는 가상 시나리오를 코드로 구현해 보겠습니다.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from webdriver_manager.chrome import ChromeDriverManager
import time
# Chrome WebDriver 자동 설정
service = Service(ChromeDriverManager().install())
options = webdriver.ChromeOptions()
# options.add_argument('--headless') # 브라우저 창을 띄우지 않고 실행
# options.add_argument('--no-sandbox')
# options.add_argument('--disable-dev-shm-usage')
driver = webdriver.Chrome(service=service, options=options)
url = '[https://shopping.some-dynamic-site.com/best-items](https://shopping.some-dynamic-site.com/best-items)'
driver.get(url)
try:
# 특정 요소가 로드될 때까지 최대 10초 대기
# 예를 들어, 상품 목록의 컨테이너 ID가 '#best-item-list'라고 가정
wait = WebDriverWait(driver, 10)
item_list_container = wait.until(
EC.presence_of_element_located((By.CSS_SELECTOR, "#best-item-list"))
)
# 페이지가 완전히 로드된 후의 HTML 소스를 가져옴
html = driver.page_source
soup = BeautifulSoup(html, 'lxml')
# 이제 BeautifulSoup으로 파싱!
items = soup.select('#best-item-list > .item')
print("--- 베스트 상품 목록 ---")
for item in items:
name = item.select_one('.item-name').get_text(strip=True)
price = item.select_one('.item-price').get_text(strip=True)
print(f"- 상품명: {name}, 가격: {price}")
finally:
# 작업이 끝나면 반드시 브라우저를 종료해야 합니다.
driver.quit()
WebDriverWait를 사용하여 특정 요소가 나타날 때까지 기다리는 것이 핵심입니다. 이를 통해 비동기적으로 로딩되는 데이터도 안정적으로 수집할 수 있습니다.
웹 스크래핑은 강력한 기술이지만, 무분별하게 사용하면 대상 서버에 큰 부하를 줄 수 있습니다. 착한 스크레이퍼가 되기 위해 다음 사항을 꼭 지켜주세요.
robots.txt 파일을 통해 크롤러가 접근해도 되는 경로와 안 되는 경로를 명시합니다. 이를 존중해야 합니다.time.sleep() 함수를 사용해 요청 사이에 적절한 간격(1~3초)을 두어 서버에 부담을 주지 않도록 합니다.requests 사용 시 헤더에 User-Agent 정보를 포함하여, 내 스크레이퍼의 정체를 밝히는 것이 좋습니다.오늘은 파이썬의 BeautifulSoup과 Selenium을 이용하여 정적, 동적 웹사이트에서 데이터를 수집하는 방법을 알아보았습니다. 이 두 가지 도구만 잘 활용해도 여러분이 원하는 거의 모든 데이터를 손에 넣을 수 있을 겁니다. 데이터를 수집하는 것에서 그치지 않고, Pandas나 Matplotlib 같은 라이브러리와 연계하여 데이터를 분석하고 시각화하는 단계로 나아가 보시길 바랍니다. 즐거운 데이터 항해 되세요!
로그인 후 댓글을 작성할 수 있습니다.