14일차 파이썬 웹 스크래핑

Peter·2025년 4월 18일
0

진도가 초고속으로 나가 수업 시간에 스크린 보고 타이핑 하기도 바쁜 나날.
오늘은 requests, BeautifulSoup, Selenium을 활용한 스크래핑 실습을 진행했다. 후반부에는 길지 않게 네이버 API 호출을 실습했다.

1.1 웹 스크래핑이란?

웹 스크래핑(Web Scraping)은 웹 사이트에서 데이터를 자동으로 추출하는 기술입니다. 프로그램이 웹 페이지를 방문하고, HTML/CSS 코드를 분석하여 원하는 정보를 수집합니다. 이 과정은 데이터 마이닝, 가격 비교, 시장 조사, 콘텐츠 수집 등 다양한 목적으로 활용됩니다.

1.2 웹 스크래핑과 API의 비교

웹 스크래핑API
웹사이트의 HTML 구조에 의존공식적으로 제공되는 데이터 접근 방식
사이트 구조 변경 시 코드 수정 필요안정적인 인터페이스 제공
모든 웹사이트에서 사용 가능API를 제공하는 서비스에만 사용 가능
사용량 제한이 명확하지 않음사용량 제한이 명확함

2.1 주요 라이브러리 소개

파이썬에서 웹 스크래핑에 사용되는 주요 라이브러리는 다음과 같습니다:
Requests: HTTP 요청을 보내고 응답을 받는 라이브러리
Beautiful Soup: HTML/XML 파싱 라이브러리
Selenium: 웹 브라우저 자동화 도구
Scrapy: 대규모 웹 크롤링을 위한 프레임워크
lxml: XML 및 HTML 처리를 위한 고성능 라이브러리
Pandas: 데이터 처리 및 분석 라이브러리

2.2 라이브러리 설치

# 기본 스크래핑 라이브러리 설치
pip install requests beautifulsoup4

# Selenium 설치
pip install selenium

3. Requests와 Beautiful Soup을 이용한 기본 스크래핑

3.1 HTTP 요청 보내기 (Requests)

# 웹 페이지 요청
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)

3.2 HTML 파싱 (Beautiful Soup)

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')

4. Selenium을 이용한 동적 웹 페이지 스크래핑

4.1 Selenium 설정

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()

4.2 Selenium 요소 선택 및 상호작용

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 순환
CAPTCHACAPTCHA 해결 서비스 사용, 인간의 개입 필요
JavaScript 로딩 콘텐츠Selenium, Playwright 같은 브라우저 자동화 도구 사용
로그인 필요세션 관리, 쿠키 사용, Selenium으로 로그인 과정 자동화
구조 변경XPath나 CSS 선택자의 견고성 확보, 정기적인 모니터링
성능 병목비동기 요청, 멀티스레딩, 분산 크롤링 사용
profile
개발자 지망생. 일단 하고보자

0개의 댓글