진도가 초고속으로 나가 수업 시간에 스크린 보고 타이핑 하기도 바쁜 나날.
오늘은 requests, BeautifulSoup, Selenium을 활용한 스크래핑 실습을 진행했다. 후반부에는 길지 않게 네이버 API 호출을 실습했다.
웹 스크래핑(Web Scraping)은 웹 사이트에서 데이터를 자동으로 추출하는 기술입니다. 프로그램이 웹 페이지를 방문하고, HTML/CSS 코드를 분석하여 원하는 정보를 수집합니다. 이 과정은 데이터 마이닝, 가격 비교, 시장 조사, 콘텐츠 수집 등 다양한 목적으로 활용됩니다.
웹 스크래핑 | API |
---|---|
웹사이트의 HTML 구조에 의존 | 공식적으로 제공되는 데이터 접근 방식 |
사이트 구조 변경 시 코드 수정 필요 | 안정적인 인터페이스 제공 |
모든 웹사이트에서 사용 가능 | API를 제공하는 서비스에만 사용 가능 |
사용량 제한이 명확하지 않음 | 사용량 제한이 명확함 |
파이썬에서 웹 스크래핑에 사용되는 주요 라이브러리는 다음과 같습니다:
Requests: HTTP 요청을 보내고 응답을 받는 라이브러리
Beautiful Soup: HTML/XML 파싱 라이브러리
Selenium: 웹 브라우저 자동화 도구
Scrapy: 대규모 웹 크롤링을 위한 프레임워크
lxml: XML 및 HTML 처리를 위한 고성능 라이브러리
Pandas: 데이터 처리 및 분석 라이브러리
# 기본 스크래핑 라이브러리 설치
pip install requests beautifulsoup4
# Selenium 설치
pip install selenium
# 웹 페이지 요청
url = 'https://example.com'
response = requests.get(url)
# 상태 코드 확인
print(f'상태 코드: {response.status_code}')
# 응답 내용 확인
print(response.text[:500])# 처음 500자만 출력# 헤더 정보 추가
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
response = requests.get(url, headers=headers)
from bs4 import BeautifulSoup
# HTML 파싱
soup = BeautifulSoup(response.text, 'html.parser')# 또는 'lxml'# 타이틀 추출
title = soup.title.text
print(f'페이지 제목: {title}')
# 요소 선택하기# 태그로 선택
paragraphs = soup.find_all('p')
print(f'단락 수: {len(paragraphs)}')
# ID로 선택
main_div = soup.find(id='main')
# 클래스로 선택
articles = soup.find_all('div', class_='article')
# CSS 선택자 사용
elements = soup.select('div.article h2')
Selenium을 사용하기 위해서는 웹 드라이버가 필요합니다. 크롬을 기준으로 설명합니다.
크롬 드라이버 다운로드: https://sites.google.com/chromium.org/driver/
다운로드한 드라이버를 PATH에 추가하거나 코드에서 경로 지정
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
import time
# Chrome 옵션 설정
chrome_options = Options()
chrome_options.add_argument("--headless")# 브라우저 창 표시 없이 실행
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
# WebDriver 초기화 (자동 설치)
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=chrome_options)
# 웹 페이지 로드
url = 'https://example.com'
driver.get(url)
# 페이지 로딩을 위한 대기
time.sleep(3)# 정적 대기 (비권장)# 페이지 소스 가져오기
page_source = driver.page_source
# Beautiful Soup으로 파싱
soup = BeautifulSoup(page_source, 'lxml')
# 브라우저 종료
driver.quit()
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# WebDriver 초기화
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
try:
# 웹 페이지 로드
driver.get('https://example.com')
# 명시적 대기: 특정 요소가 나타날 때까지 최대 10초 기다림
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "myDynamicElement"))
)
# 다양한 방법으로 요소 찾기# ID로 찾기
element_by_id = driver.find_element(By.ID, 'elementId')
# 클래스로 찾기
elements_by_class = driver.find_elements(By.CLASS_NAME, 'className')
# CSS 선택자로 찾기
element_by_css = driver.find_element(By.CSS_SELECTOR, 'div.class > p')
# XPath로 찾기
element_by_xpath = driver.find_element(By.XPATH, '//div[@id="main"]//h2')
# 상호작용# 클릭
element_by_id.click()
# 텍스트 입력
input_element = driver.find_element(By.NAME, 'search')
input_element.clear()# 기존 내용 지우기
input_element.send_keys('검색어')
# 폼 제출
form = driver.find_element(By.ID, 'searchForm')
form.submit()
# 스크롤
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# 스크린샷 저장
driver.save_screenshot('screenshot.png')
# 페이지 소스 가져오기
html = driver.page_source
# Beautiful Soup으로 파싱
soup = BeautifulSoup(html, 'lxml')
finally:
# 브라우저 종료
driver.quit()
문제 | 해결책 |
---|---|
IP 차단 | 프록시 사용, 요청 간 지연 추가, User-Agent 순환 |
CAPTCHA | CAPTCHA 해결 서비스 사용, 인간의 개입 필요 |
JavaScript 로딩 콘텐츠 | Selenium, Playwright 같은 브라우저 자동화 도구 사용 |
로그인 필요 | 세션 관리, 쿠키 사용, Selenium으로 로그인 과정 자동화 |
구조 변경 | XPath나 CSS 선택자의 견고성 확보, 정기적인 모니터링 |
성능 병목 | 비동기 요청, 멀티스레딩, 분산 크롤링 사용 |