Python 웹 스크래핑 실전: BeautifulSoup과 Selenium으로 데이터 수집

오늘날 데이터는 정보의 원천이자 경쟁력의 핵심입니다. 웹에 산재한 방대한 데이터를 어떻게 효율적으로 수집하고 활용할 수 있을까요? 이 글에서는 Python을 활용하여 웹사이트로부터 데이터를 자동으로 수집하는 실전 방법을 체계적으로 다룹니다. 특히 BeautifulSoup과 Selenium을 중심으로, 초보자와 중급 사용자 모두가 실전에 바로 활용할 수 있도록 친절히 설명드리겠습니다.


Python으로 시작하는 웹 스크래핑 실전: BeautifulSoup과 Selenium으로 데이터 수집하기

목차


1. 서론 : 데이터의 바다에서 정보를 낚아올리는 기술

인터넷은 매일 수백억 개 이상의 웹페이지가 생성되고, 업데이트되는 방대한 데이터의 보고(寶庫)입니다. 하지만 필요한 정보를 단순히 수작업으로 찾아 저장하는 것은 사실상 불가능에 가깝습니다. 여기서 웹 스크래핑(Web Scraping)이라는 강력한 기술이 등장합니다. 웹 스크래핑은 웹사이트로부터 원하는 데이터를 자동으로 추출하는 과정을 의미하며, 시간과 노력을 절약할 수 있을 뿐만 아니라, 데이터 기반 의사결정의 토대를 마련해줍니다.

예를 들어, 쇼핑몰의 가격 정보를 비교하거나, 뉴스 사이트의 최신 기사 목록을 모니터링하거나, 부동산 매물 데이터를 수집하는 일들은 모두 웹 스크래핑으로 자동화할 수 있습니다. 특히 Python은 이 분야에서 가장 인기 있는 언어로, 다양한 라이브러리와 함께 직관적이고 강력한 기능을 제공합니다.

그러나 웹 스크래핑을 시작하기에 앞서 한 가지 짚고 넘어가야 할 중요한 점이 있습니다. 바로 ‘법적 이슈’입니다. 대부분의 사이트는 robots.txt 파일을 통해 크롤링 정책을 명시하고 있으며, 무단으로 대량 수집할 경우 법적 책임이 따를 수 있습니다. 따라서 항상 사이트의 이용 약관과 정책을 확인하고, 윤리적인 방식으로 데이터를 수집하는 것이 중요합니다.

이제 본격적으로 Python을 활용한 웹 스크래핑의 세계로 함께 떠나보겠습니다. 이 글을 따라가다 보면, 누구나 웹페이지 속 숨겨진 정보를 낚아올릴 수 있는 기술을 손에 넣게 될 것입니다.


2. 웹 스크래핑의 기본 개념 이해하기

웹 스크래핑을 제대로 이해하려면 먼저 웹페이지가 어떻게 구성되고 작동하는지를 알아야 합니다. 웹페이지는 주로 HTML(HyperText Markup Language)이라는 구조화된 언어로 작성되며, 각 요소들은 DOM(Document Object Model)이라는 트리 구조로 표현됩니다. DOM은 웹 브라우저가 HTML 문서를 이해하고 조작하는 방식이며, 스크래핑 도구는 이 구조를 분석하여 원하는 데이터를 찾아냅니다.

웹페이지에 접속할 때 우리는 HTTP(HyperText Transfer Protocol)를 통해 서버에 요청(Request)을 보내고, 서버는 이에 대한 응답(Response)으로 HTML, JSON, XML 등의 데이터를 반환합니다. 웹 스크래핑은 이 흐름을 자동화하여, 수동으로 웹브라우저를 통해 보는 대신 프로그램이 직접 데이터를 가져오고 필요한 정보를 추출하는 과정을 의미합니다.

하지만 모든 웹사이트가 무조건 자유롭게 스크래핑을 허용하는 것은 아닙니다. 이를 판단하는 기준 중 하나가 바로 robots.txt 파일입니다. 이 파일은 웹사이트 최상위 디렉토리에 위치하며, 어떤 페이지는 크롤러가 접근할 수 있고, 어떤 페이지는 접근이 금지되는지를 명시합니다. 스크래핑을 진행하기 전에는 항상 robots.txt를 확인하여 사이트의 정책을 준수하는 것이 중요합니다.

또한, 웹 스크래핑을 할 때는 몇 가지 매너를 지키는 것이 필요합니다. 예를 들어, 요청(request)을 너무 빠르게 보내지 말고, 적절한 시간 간격을 두어야 하며, 과도한 트래픽을 발생시켜 서버에 부담을 주지 않도록 주의해야 합니다. 이는 기술적인 문제뿐만 아니라, 윤리적 책임을 지는 기본적인 태도이기도 합니다.


Python 웹 스크래핑 도구 소개

3. Python 웹 스크래핑 도구 소개

Python은 웹 스크래핑을 위한 다양한 도구와 라이브러리를 제공합니다. 각각의 도구는 특성과 목적이 조금씩 다르기 때문에, 상황에 맞게 선택하여 사용하는 것이 중요합니다. 이번 섹션에서는 웹 스크래핑에서 가장 널리 사용되는 주요 라이브러리들을 소개합니다.

BeautifulSoup

BeautifulSoup은 HTML과 XML 파일을 파싱(parse)하는 데 특화된 Python 라이브러리입니다. 구문이 매우 직관적이며, 문서 내 특정 태그를 쉽게 탐색하고, 수정하거나 추출할 수 있습니다. 가벼운 웹 스크래핑 작업이나 정적 웹페이지를 다룰 때 가장 많이 사용됩니다. 특히 CSS 선택자 기반의 탐색이 가능하여 초보자도 빠르게 학습할 수 있습니다.

Selenium

Selenium은 원래 웹 애플리케이션 테스트 자동화를 위해 개발된 프레임워크이지만, 웹 스크래핑에도 매우 유용하게 활용됩니다. 특히 JavaScript로 동적으로 렌더링되는 웹페이지를 다룰 때 필수적입니다. Selenium을 사용하면 실제 브라우저를 열고, 버튼을 클릭하거나 스크롤을 내리는 등 인간처럼 웹사이트를 조작할 수 있습니다.

Requests

Requests는 HTTP 요청을 보내고 응답을 받아오는 가장 기본적이고 강력한 Python 라이브러리입니다. 간단한 코드로 GET, POST 요청을 수행할 수 있으며, BeautifulSoup과 함께 사용하여 웹페이지의 HTML을 가져오는 역할을 주로 합니다. 설치와 사용이 매우 간편하여, 웹 스크래핑의 첫걸음으로 가장 많이 활용됩니다.

비교 표

도구 주요 특징 사용 예시
BeautifulSoup 정적 HTML 파싱, 간단하고 직관적 블로그 글, 뉴스 기사 수집
Selenium 동적 웹페이지 조작, 실제 브라우저 구동 로그인 후 데이터 추출, 무한스크롤 사이트 크롤링
Requests HTTP 통신 담당, 빠르고 간단 HTML 문서 가져오기, API 호출

4. BeautifulSoup을 활용한 웹 스크래핑 실습


BeautifulSoup을 활용한 웹 스크래핑 실습

이제부터는 실제로 Python을 사용하여 웹페이지로부터 데이터를 수집하는 과정을 살펴보겠습니다. 첫 번째로, 가장 기본적이면서도 강력한 BeautifulSoup을 활용하는 방법을 실습해보겠습니다.

환경 세팅

웹 스크래핑을 시작하려면 필요한 라이브러리를 먼저 설치해야 합니다. 아래 명령어를 사용하여 BeautifulSoup과 Requests를 설치할 수 있습니다.

pip install beautifulsoup4
pip install requests

requests로 HTML 가져오기

웹페이지의 HTML 소스를 가져오기 위해 requests 라이브러리를 사용합니다. 예를 들어, 특정 뉴스 사이트의 메인 페이지를 가져오는 코드는 다음과 같습니다.

import requests

url = "https://example.com"
response = requests.get(url)

# 가져온 HTML 소스 출력
print(response.text)

BeautifulSoup으로 HTML 파싱

가져온 HTML 소스를 BeautifulSoup으로 파싱하여 문서 구조를 분석할 수 있습니다. BeautifulSoup 객체를 생성하고, HTML 요소를 다루는 기본적인 방법은 다음과 같습니다.

from bs4 import BeautifulSoup

soup = BeautifulSoup(response.text, "html.parser")

# 예시: 페이지 제목(title 태그) 가져오기
print(soup.title.text)

원하는 데이터 추출하기

BeautifulSoup을 사용하면 다양한 방법으로 특정 요소를 추출할 수 있습니다. 대표적으로 find(), find_all(), select() 메서드를 활용할 수 있습니다.

  • find(): 첫 번째로 일치하는 태그를 반환합니다.
  • find_all(): 조건에 일치하는 모든 태그를 리스트로 반환합니다.
  • select(): CSS 선택자 기반으로 요소를 찾습니다.

예를 들어, 웹페이지 내 모든 기사 제목을 가져오는 코드는 다음과 같습니다.

# 모든 h2 태그 안에 있는 기사 제목 찾기
headlines = soup.find_all('h2')

for headline in headlines:
    print(headline.text)

또는 CSS 선택자를 사용하여 특정 클래스를 가진 요소만 선택할 수도 있습니다.

# 클래스명이 "article-title"인 모든 요소 선택
articles = soup.select('.article-title')

for article in articles:
    print(article.get_text())

이렇게 BeautifulSoup을 사용하면 간단한 코드로도 HTML 구조를 손쉽게 탐색하고 필요한 데이터를 추출할 수 있습니다. 다음 단락에서는 동적 웹페이지를 다루는 Selenium 활용법을 알아보겠습니다.


5. Selenium을 활용한 웹 스크래핑 실습


Selenium을 활용한 웹 스크래핑 실습

BeautifulSoup은 정적 페이지를 스크래핑할 때 강력한 도구지만, JavaScript로 동적으로 렌더링되는 웹페이지를 다루기에는 한계가 있습니다. 이때는 Selenium을 활용하여 실제 브라우저를 자동으로 제어하며 데이터를 수집할 수 있습니다. Selenium은 웹 테스트 자동화 도구로 시작했지만, 현재는 웹 스크래핑에도 폭넓게 사용되고 있습니다.

환경 세팅

먼저 Selenium과 웹드라이버를 설치해야 합니다. Chrome 브라우저를 기준으로 ChromeDriver를 사용할 것이며, 다음 명령어로 Selenium을 설치할 수 있습니다.

pip install selenium

ChromeDriver는 사용 중인 Chrome 브라우저 버전에 맞는 버전을 설치해야 하며, 설치 후 실행 파일의 경로를 프로그램에 지정해야 합니다.

브라우저 자동화 기초

설치가 완료되면 Selenium을 통해 실제 브라우저를 열고 페이지에 접근할 수 있습니다. 기본적인 사용 방법은 다음과 같습니다.

from selenium import webdriver

# ChromeDriver 경로 지정
driver = webdriver.Chrome(executable_path="path/to/chromedriver")

# 웹페이지 열기
driver.get("https://example.com")

# 현재 페이지 제목 출력
print(driver.title)

# 브라우저 종료
driver.quit()

요소 찾기

Selenium은 웹페이지 내 요소를 다양한 방법으로 찾을 수 있습니다. 대표적으로 다음과 같은 방식이 있습니다.

  • By.ID : ID 속성으로 요소 찾기
  • By.CLASS_NAME : 클래스 이름으로 요소 찾기
  • By.NAME : name 속성으로 요소 찾기
  • By.XPATH : XPath 표현식으로 요소 찾기

예를 들어, 특정 버튼을 클릭하려면 다음과 같은 코드를 사용할 수 있습니다.

from selenium.webdriver.common.by import By

# ID를 이용하여 버튼 클릭
button = driver.find_element(By.ID, "submit-button")
button.click()

스크롤 내리기와 페이지 이동

동적 로딩이 필요한 페이지에서는 스크롤을 내려 추가 데이터를 로딩할 필요가 있습니다. Selenium은 JavaScript 명령어를 실행하여 스크롤을 제어할 수 있습니다.

# 페이지 최하단까지 스크롤
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

또한, 다음 페이지로 넘어가기 위해 링크를 클릭하거나 URL을 직접 변경하는 등의 작업도 가능합니다.

실전 예제: 로그인 필요한 사이트 스크래핑

로그인이 필요한 웹사이트에서 데이터를 스크래핑하는 경우, 로그인 폼에 아이디와 비밀번호를 입력하고 로그인 버튼을 클릭하는 방식으로 접근할 수 있습니다. 예시는 다음과 같습니다.

# 로그인 페이지 접속
driver.get("https://example.com/login")

# 아이디 입력
username_input = driver.find_element(By.NAME, "username")
username_input.send_keys("your_username")

# 비밀번호 입력
password_input = driver.find_element(By.NAME, "password")
password_input.send_keys("your_password")

# 로그인 버튼 클릭
login_button = driver.find_element(By.XPATH, '//button[@type="submit"]')
login_button.click()

로그인 후에는 인증 세션을 유지한 채로 원하는 페이지를 탐색하고 필요한 데이터를 수집할 수 있습니다. Selenium은 이처럼 복잡한 사용자 인터랙션을 자동화할 수 있다는 점에서 매우 강력한 도구입니다.


6. 실전 프로젝트: 뉴스 기사 제목 스크래핑하기

이제까지 배운 내용을 실제로 적용해보는 실습 프로젝트를 진행해보겠습니다. 이번 프로젝트에서는 특정 뉴스 사이트의 메인 페이지에서 기사 제목을 수집하는 작업을 BeautifulSoup과 Selenium을 각각 활용하여 구현해보겠습니다. 두 방법을 비교함으로써 각각의 장단점을 보다 명확히 이해할 수 있습니다.

목표 설정

뉴스 사이트의 메인 페이지에 접속하여, 최신 기사 제목 리스트를 수집하고 출력하는 것이 이번 실습의 목표입니다. 실습은 임의의 뉴스 사이트 예제(https://example-news.com)를 기반으로 진행합니다.

BeautifulSoup을 이용한 기사 제목 스크래핑

정적 페이지라면 BeautifulSoup을 활용하여 간단하게 기사 제목을 추출할 수 있습니다. 예시는 다음과 같습니다.

import requests
from bs4 import BeautifulSoup

# 대상 URL
url = "https://example-news.com"

# HTML 가져오기
response = requests.get(url)

# BeautifulSoup으로 파싱
soup = BeautifulSoup(response.text, "html.parser")

# 기사 제목 선택 (가상의 클래스명 사용)
headlines = soup.select(".headline-title")

# 기사 제목 출력
for idx, headline in enumerate(headlines, 1):
    print(f"{idx}. {headline.get_text()}")

Selenium을 이용한 기사 제목 스크래핑

만약 뉴스 사이트가 JavaScript로 콘텐츠를 렌더링한다면 Selenium을 활용해야 합니다. Selenium을 사용한 예제 코드는 다음과 같습니다.

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

# ChromeDriver 경로 설정
driver = webdriver.Chrome(executable_path="path/to/chromedriver")

# 페이지 접속
driver.get("https://example-news.com")

# 페이지 로딩 대기
time.sleep(3)

# 기사 제목 요소 찾기
headlines = driver.find_elements(By.CLASS_NAME, "headline-title")

# 기사 제목 출력
for idx, headline in enumerate(headlines, 1):
    print(f"{idx}. {headline.text}")

# 브라우저 종료
driver.quit()

코드를 통한 비교 분석

기술 장점 단점
BeautifulSoup 속도가 빠르고 코드가 간결함 동적 콘텐츠 수집 불가
Selenium JavaScript 렌더링 처리 가능 브라우저 구동으로 느리고 무겁다

프로젝트를 통해 BeautifulSoup과 Selenium 각각의 특성과 사용해야 할 상황을 구체적으로 이해할 수 있습니다. 정적 데이터라면 BeautifulSoup을, 동적 데이터라면 Selenium을 선택하는 것이 효율적입니다.


7. 웹 스크래핑 시 주의할 점과 팁

웹 스크래핑은 매우 유용한 기술이지만, 몇 가지 중요한 주의사항과 효율적인 수행을 위한 팁을 반드시 숙지해야 합니다. 무분별한 스크래핑은 서버에 부담을 주거나 법적인 문제를 야기할 수 있으며, 효율적인 스크래핑을 위해서는 최적화 전략이 필요합니다.

요청 간 시간 지연 적용

웹사이트에 요청을 보낼 때는 적절한 시간 간격을 두어야 합니다. 이를 통해 서버에 과도한 부하를 주는 것을 방지할 수 있습니다. Python에서는 time.sleep() 함수를 사용하여 요청 간 지연을 설정할 수 있습니다.

import time

# 요청 후 2초 대기
time.sleep(2)

User-Agent 설정하기

일부 웹사이트는 기본 Python requests의 User-Agent를 감지하고 차단할 수 있습니다. 이를 방지하기 위해 요청 헤더에 브라우저 User-Agent를 설정하는 것이 좋습니다.

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36"
}

response = requests.get(url, headers=headers)

IP 차단 대응 방법 (Proxy, VPN)

지속적이고 빈번한 스크래핑은 웹사이트로부터 IP 차단을 초래할 수 있습니다. 이를 방지하기 위해 Proxy 서버를 사용하거나, VPN을 이용하여 IP를 주기적으로 변경하는 방법을 고려할 수 있습니다. 다음은 requests를 통해 Proxy를 설정하는 예시입니다.

proxies = {
    "http": "http://your_proxy_address:port",
    "https": "https://your_proxy_address:port",
}

response = requests.get(url, headers=headers, proxies=proxies)

다만, Proxy나 VPN을 사용할 경우에도 서비스 이용 약관을 준수하고, 비윤리적 활동을 삼가야 합니다.

수집한 데이터 저장하기

스크래핑한 데이터를 효율적으로 저장하고 관리하기 위해 CSV 또는 JSON 포맷을 사용하는 것이 일반적입니다. Python의 내장 csv 모듈이나 json 모듈을 사용하면 쉽게 데이터를 파일로 저장할 수 있습니다.

CSV 파일 저장 예시:

import csv

data = [["Title 1"], ["Title 2"], ["Title 3"]]

with open('data.csv', 'w', newline='', encoding='utf-8') as file:
    writer = csv.writer(file)
    writer.writerow(["Title"])
    writer.writerows(data)

JSON 파일 저장 예시:

import json

data = {"titles": ["Title 1", "Title 2", "Title 3"]}

with open('data.json', 'w', encoding='utf-8') as file:
    json.dump(data, file, ensure_ascii=False, indent=4)

데이터 저장 방식을 잘 선택하면 향후 데이터 분석이나 추가 가공 작업을 훨씬 수월하게 진행할 수 있습니다.


8. 마치며: 웹 스크래핑을 통해 데이터 수집 능력 기르기

웹 스크래핑은 단순히 데이터를 긁어오는 기술을 넘어, 방대한 정보의 바다 속에서 필요한 데이터를 선별하고, 이를 활용하여 새로운 가치를 창출하는 능력입니다. BeautifulSoup과 Selenium을 활용하면 정적 페이지는 물론, 동적 페이지에서도 필요한 정보를 자유자재로 수집할 수 있으며, 이를 기반으로 데이터 분석, 가격 모니터링, 시장 조사, 트렌드 분석 등 다양한 영역에서 실질적인 인사이트를 얻을 수 있습니다.

하지만 기술적 숙련도뿐만 아니라, 윤리적 책임감도 함께 가져야 합니다. 크롤링 대상 사이트의 이용 약관을 존중하고, 서버에 과도한 부하를 주지 않으며, 데이터의 적법성과 개인 정보 보호를 항상 염두에 두어야 합니다. 올바른 방법으로 스크래핑을 수행할 때, 이 기술은 비즈니스와 연구, 개인 프로젝트를 혁신하는 강력한 무기가 될 것입니다.

이제 여러분은 웹 스크래핑의 기본기를 탄탄히 다졌습니다. 앞으로는 Scrapy 같은 전문 프레임워크를 학습하거나, 웹 API를 통해 공식적으로 데이터를 가져오는 방법도 함께 익혀 나간다면 더욱 견고한 데이터 수집 역량을 갖출 수 있을 것입니다. 데이터 기반 시대를 살아가는 지금, 웹 스크래핑은 선택이 아니라 필수입니다. 직접 손으로 데이터를 모으고 가공하는 힘을 키워, 새로운 기회의 문을 열어보시길 바랍니다.

댓글 남기기

Table of Contents