본문으로 건너뛰기
실습하기

JavaScript와 동적 웹 크롤링

웹 페이지는 HTML, CSS, JavScript 이 3가지가 결합되어 만들어집니다.

HTML은 웹 페이지의 구조를 정의하고, CSS는 웹 페이지의 스타일을 정의합니다.

JavaScript는 언어는 웹 페이지를 동적(Dynamic)으로 만듭니다.

여기서 동적이라는 단어의 의미는 사용자와 상호작용하거나, 특정 이벤트에 반응하여 웹 페이지의 콘텐츠가 바뀌는 것을 의미합니다.

예를 들어 JavaScript를 활용하면 사용자가 버튼을 클릭했을 때 새로운 내용을 표시하거나, 사용자의 스크롤에 따라 추가적인 콘텐츠를 불러올 수 있습니다.

이러한 동적 콘텐츠는 웹 페이지를 처음 불러올 때는 존재하지 않다가, 웹 브라우저에서 JavaScript를 실행하면서 동적으로 생성됩니다.


BeautifulSoup의 한계

BeautifulSoupHTML을 분석해 데이터를 가져옵니다.

하지만 JavaScript를 활용해 동적으로 생성된 콘텐츠는 BeautifulSoup으로 가져올 수 없습니다.


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_elementfeels_like_elementNone을 반환합니다.

이는 JavaScript가 실행되기 전의 HTML만 가져오기 때문에 해당 요소를 찾을 수 없기 때문입니다.


Selenium을 활용한 동적 웹 크롤링

기상청 홈페이지는 JavaScript를 활용해 동적으로 날씨 정보를 표시하기 때문에 BeautifulSoup으로는 데이터를 제대로 가져올 수 없습니다.

하지만 Selenium(셀레니움)을 사용하면 실제 브라우저에서 JavaScript가 실행된 후의 화면을 가져와, 이러한 문제를 해결할 수 있습니다.

참고 : 실습 코드를 컴퓨터에서 실제로 실행하려면, pip install selenium 명령어로 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 강의를 등록해 주세요!