1. 개요

회사 백오피스 서비스 개발에서 뉴스기사 크롤링 모듈 개발을 담당 하였다. 해당 요구사항이 있어 이를 충족하기 위해 Python 에 크롤링 패키지를 찾아보았다.
대표적으로 Beautiful Soup 과 Selenium 이 있었다. 둘다 써보고 보다 적합한 패키지를 결정하고자 하였고 이에 대해 기술한 내용이다.
2. 본론
2.1. Selenium vs Beautiful Soup (+ requests)
Selenium 과 Beutiful Soup 은 웹 데이터를 수집하는데에 특화된 패키지이지만, 작동 방식에서 큰 차이가 있어 목적에 따라 선택할 수 있다.
2.1.1. Selenium
Selenium 은 기본적으로 크롬이나 파이어폭스 같은 실제 브라우저 창을 띄운다.
Selenium 은 단순히 코드가 브라우저를 직접 조작하는 것이 아니라, 중간에 WebDriver 를 두고 통신한다. 이 WebDriver 를 통해 타깃 웹 화면을 로컬에 띄우고 JavaScript 를 실행하여 DOM 을 렌더링 한다. 브라우저 엔진 전체를 메모리에 올리기 때문에 CPU & RAM 을 점유하게 되고 웹 페이지 내 모든 요소가 배치 되야 하기 때문에 기다려야 한다.
import os
from dotenv import load_dotenv
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from webdriver_manager.chrome import ChromeDriverManager # ChromeDriver
def selenium_test():
options = Options()
options.add_experimental_option('detach', True)
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service, options=options)
url = os.getenv('DONGA_URL')
driver.get(url)
return driver
driver.get(url) 시 랜더링이 시작되고 실제로 화면이 약 5초 소요 후 표출된다.

일반 사용자가 브라우저를 쓰는 것과 100% 동일한 환경 이 구축되어, 요소에 접근하여 데이터를 추출할 수 있고, 아직 해보진 않았으나 로그인 등을 자동화 할 수 있다고 한다.
다만, 현재 단순 뉴스 기사 크롤링인 기능에 반해 너무 무거운 패키지이기에 적합하지 않다고 판단했다.
2.1.2. Beautiful Soup(+ requests)
Beautiful Soup 은 requests 패키지와 같이 사용한다.
requests 로 타깃 url 의 정적 html 텍스트를 긁어오고, Beautiful Soup 으로 쉽게 추출하는 방식이다.
Selenium 에서 접근했던 url 을 대상으로 테스트 해봤을 때,
print(f"전자 신문 크롤링 테스트")
url = "https://www.etnews.com/20250502000165"
search = requests.get(url)
soup = BeautifulSoup(search.text, "lxml")
print(f"html : {soup}")

BeautifulSoup 인스턴스 출력시 정적 html 태그가 나오는 것을 확인 할 수 있다.
출력시엔 String 값으로 타입을 변환하긴 하지만, 엄밀히 보면 BeutifulSoup 객체이다.
파이썬의 모든 객체는 __str__ 또는 __repr__ 이라는 내부 메서드가 있기 때문에 print() 함수 호출시 문자열로 반환되기 때문.
이 객체에는 HTML 계층 구조가 통째로 들어가 있는 상태이다. 그렇기 때문에 특정 부모(Container) 안에 있는 자식 (Element) 를 찾는 방법을 통해 쉽게 웹 특정 데이터에 접근할 수 있는 것이다. 특정 Element 의 css Selector 를 통해 값을 추출 하는 것을 보면 더 쉽게 이해할 수 있다.
2.2. find 메소드를 통한 데이터 추출
구조에 따라 조금 쓰임세가 다를 수 있지만, 기본적으로 아래 메소드 구조와 같은 방식으로 접근이 가능하다.
BeatifulSoup.find("{태그명}", attrs={"{class 또는 속성값}": "{클래스명}"}).find("{태그}").getText()
다음 뉴스 기사에서 해당 뉴스 제목을 추출한다고 했을 때,

구조는 다음과 같다.
[부모 요소]
tag: <selection>
class: head_group
[자식 요소]
tag: <h1>
해당 제목을 추출하고 싶으면 다음과 같이 작성 할 수 있다.
normal_soup.find("section", attrs={"class": "head_group"}).find("h1").getText()
제목, 본문, 날짜, 이미지 모두 이와 같은 방법으로 추출 할 수 있다.
2.3. 참고자료
'dev > backend' 카테고리의 다른 글
| [Python] KoNLPy 자연어 형태소 분석 (0) | 2025.12.29 |
|---|---|
| [Python] SQLalchemy ORM (0) | 2025.12.24 |
| [Python] pip 패키지 목록 자동생성 (0) | 2025.12.24 |
| [Python] windows .venv 세팅 (1) | 2025.12.22 |
| [Spring] Spring MVC (0) | 2025.09.15 |
