JavaScript와 동적 웹 크롤링
웹 페이지는 HTML
, CSS
, JavScript
이 3가지가 결합되어 만들어집니다.
HTML
은 웹 페이지의 구조를 정의하고, CSS
는 웹 페이지의 스타일을 정의합니다.
JavaScript
는 언어는 웹 페이지를 동적(Dynamic)으로 만듭니다.
여기서 동적이라는 단어의 의미는 사용자와 상호작용하거나, 특정 이벤트에 반응하여 웹 페이지의 콘텐츠가 바뀌는 것을 의미합니다.
예를 들어 JavaScript를 활용하면 사용자가 버튼을 클릭했을 때 새로운 내용을 표시하거나, 사용자의 스크롤에 따라 추가적인 콘텐츠를 불러올 수 있습니다.
이러한 동적 콘텐츠는 웹 페이지를 처음 불러올 때는 존재하지 않다가, 웹 브라우저에서 JavaScript를 실행하면서 동적으로 생성됩니다.
BeautifulSoup의 한계
BeautifulSoup은 HTML
을 분석해 데이터를 가져옵니다.
하지만 JavaScript
를 활용해 동적으로 생성된 콘텐츠는 BeautifulSoup으로 가져올 수 없습니다.
BeautifulSoup으로 크롤링이 불가한 코드 예제
먼저 BeautifulSoup을 사용해 기상청 홈페이지에서 현재 기온과 체감 온도를 가져오는 코드를 살펴보겠습니다.
import requests
from bs4 import BeautifulSoup
# 기상청 홈페이지 URL
url = 'https://www.weather.go.kr/w/index.do'
# 페이지 요청
response = requests.get(url)
# BeautifulSoup으로 HTML 파싱
soup = BeautifulSoup(response.text, 'html.parser')
# 기온과 체감온도 찾기
# 'tmp' 클래스는 현재 기온을 나타내고, 'chill' 클래스는 체감온도를 나타냄
temperature_element = soup.find('span', class_='tmp')
feels_like_element = soup.find('span', class_='chill')
# 텍스트 추출
temperature = temperature_element.text.strip() if temperature_element else 'N/A'
feels_like = feels_like_element.text.strip() if feels_like_element else 'N/A'
# 결과 출력
print(f"오늘의 기온: {temperature}")
print(f"체감온도: {feels_like}")
위 코드는 BeautifulSoup으로 기상청 홈페이지의 날씨 정보를 가져오려고 시도하지만, temperature_element
와 feels_like_element
가 None
을 반환합니다.
이는 JavaScript가 실행되기 전의 HTML만 가져오기 때문에 해당 요소를 찾을 수 없기 때문입니다.
Selenium을 활용한 동적 웹 크롤링
기상청 홈페이지는 JavaScript를 활용해 동적으로 날씨 정보를 표시하기 때문에 BeautifulSoup으로는 데이터를 제대로 가져올 수 없습니다.
하지만 Selenium(셀레니움)
을 사용하면 실제 브라우저에서 JavaScript가 실행된 후의 화면을 가져와, 이러한 문제를 해결할 수 있습니다.
참고 : 실습 코드를 컴퓨터에서 실제로 실행하려면,
pip install selenium
명령어로 Selenium 라이브러리를 설치해야 합니다.
from selenium import webdriver
from selenium.webdriver.common.by import By
# Chrome 브라우저 열기
driver = webdriver.Chrome()
# 기상청 동네 예보 페이지 열기
url = "https://www.weather.go.kr/w/index.do"
driver.get(url)
# 기온과 체감온도 찾기
# 'tmp' 클래스는 현재 기온을 나타내고, 'chill' 클래스는 체감온도를 나타냄
temperature_element = driver.find_element(By.CLASS_NAME, 'tmp')
feels_like_element = driver.find_element(By.CLASS_NAME, 'chill')
# 텍스트 추출
temperature = temperature_element.text
feels_like = feels_like_element.text
# 결과 출력
print(f"오늘의 기온: {temperature}")
print(f"체감온도: {feels_like}")
# WebDriver 종료
driver.quit()
코드 상세 설명
-
driver = webdriver.Chrome()
: Chrome 브라우저를 열고, driver 객체 생성 -
driver.get(url)
: 지정한 URL(기상청 홈페이지)로 이동 -
temperature_element = driver.find_element(By.CLASS_NAME, 'tmp')
: tmp 클래스를 가진 요소를 찾아 temperature_element에 저장 -
feels_like_element = driver.find_element(By.CLASS_NAME, 'chill')
: chill 클래스를 가진 요소를 찾아 feels_like_element에 저장 -
temperature = temperature_element.text
: temperature_element의 텍스트를 추출하여 temperature에 저장 -
feels_like = feels_like_element.text
: feels_like_element의 텍스트를 추출하여 feels_like에 저장 -
driver.quit()
: WebDriver 종료
오늘의 기온: 30.4℃
체감온도: 체감(30.6℃)
이렇게 Selenium을 사용하면 JavaScript로 동적으로 생성된 콘텐츠를 크롤링할 수 있습니다.
다음 내용이 궁금하다면?
코드프렌즈 PLUS 멤버십 가입 or 강의를 등록해 주세요!