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

Selenium으로 미국 주가 지수 크롤링하기

이번 수업에서는 지금까지 배운 Selenium 지식을 활용해 실무 수준의 웹 크롤링을 실습해보겠습니다.

실습 화면의 코드는 Selenium을 사용하여 Yahoo Finance 웹사이트에서 Americas 섹션의 테이블 데이터를 추출하고, 그 데이터를 pandas 라이브러리를 이용해 정리하여 출력하는 예제입니다.

참고 : 웹 크롤링은 웹사이트의 HTML, CSS 구조가 바뀌면 코드가 동작하지 않을 수 있습니다. 웹사이트의 구조가 변경되면 코드를 이에 맞게 수정해야 합니다.

코드를 단계별로 차근차근 살펴보겠습니다.


1. 필수 라이브러리 임포트

라이브러리 불러오기
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import pandas as pd
import time
  • selenium : 웹 자동화 및 스크래핑을 위한 라이브러리입니다. 웹 페이지에서 요소를 찾고 상호작용할 수 있습니다.

  • pandas : 데이터를 표 형식으로 다룰 수 있는 라이브러리로, 엑셀과 비슷한 방식으로 데이터를 분석할 때 유용합니다.

  • time : 시간 관련 함수를 제공하는 파이썬 내장 모듈입니다.


2. 웹드라이버 실행 및 웹사이트 이동

Selenium 웹드라이버 실행 및 웹사이트 이동
driver = webdriver.Chrome()
driver.get('https://finance.yahoo.com/markets/')
  • webdriver.Chrome() : 크롬 브라우저를 자동으로 제어하기 위해 Chrome 웹드라이버를 실행합니다. 드라이버를 사용해 웹 브라우저 창을 엽니다.

  • driver.get(URL) : 주어진 URL로 이동합니다. 여기서는 Yahoo Finance의 'Markets' 페이지로 이동합니다.


3. 페이지 로딩 대기

페이지 10초 대기
wait = WebDriverWait(driver, 10)
  • WebDriverWait(driver, 10) : 최대 10초 동안 요소가 나타날 때까지 대기합니다. 페이지가 다 로드되기 전에 코드를 실행하면 오류가 발생할 수 있으므로, 특정 요소가 나타날 때까지 기다립니다.

4. 'Americas' 섹션 찾기

특정 섹션 찾기
americas_section = wait.until(EC.presence_of_element_located((By.XPATH, "//h3[text()='Americas']")))
  • wait.until() : 'Americas'라는 텍스트를 가진 h3 태그가 페이지에 나타날 때까지 기다립니다. EC.presence_of_element_located()는 해당 요소가 페이지에 나타나는지 확인하는 조건입니다.

5. 스크롤 이동 및 섹션 내부 테이블 찾기

특정 섹션의 테이블 찾기
actions = ActionChains(driver)
actions.move_to_element(americas_section).perform()

parent_section = americas_section.find_element(By.XPATH, "./ancestor::section[contains(@data-testid, 'world-indices')]")
table = parent_section.find_element(By.XPATH, ".//table")
  • ActionChains(driver) : 페이지에서 마우스를 움직이거나 클릭하는 동작을 자동화할 때 사용됩니다. 여기서는 'Americas' 섹션으로 스크롤을 이동합니다.

  • find_element(By.XPATH) : 'Americas' 섹션의 부모 요소인 section 태그 안에서 테이블을 찾습니다.


6. 테이블 데이터 추출

테이블 내 데이터 추출하기
headers = [header.text for header in table.find_elements(By.XPATH, ".//th")]
rows = table.find_elements(By.XPATH, ".//tbody/tr")
  • table.find_elements(): 테이블의 헤더와 각 행의 데이터를 추출합니다.

    • th : 테이블의 헤더 정보를 의미합니다.

    • tr : 테이블의 행을 의미합니다.


7. 데이터를 리스트로 저장

테이블 내 데이터를 딕셔너리로 저장
table_data = []
for row in rows:
columns = row.find_elements(By.XPATH, ".//td")
row_data = {}
for i in range(len(headers)):
header = headers[i]
column_value = columns[i].text
row_data[header] = column_value
table_data.append(row_data)
  • 각 행(tr)의 열 데이터(td)를 추출한 후, 헤더와 일치하는 값들을 딕셔너리로 저장합니다. 최종적으로 딕셔너리를 리스트에 추가합니다.

8. 데이터를 판다스 데이터프레임으로 변환 및 출력

데이터프레임으로 변환 및 출력
df = pd.DataFrame(table_data)
df_filtered = df[['Name', 'Price']]
print(df_filtered)
  • pd.DataFrame(): 추출된 데이터를 판다스 데이터프레임으로 변환합니다.

  • df[['Name', 'Price']]: NamePrice 컬럼만 필터링하여 정리된 데이터를 출력합니다.


9. 브라우저 종료

브라우저 종료
driver.quit()
  • driver.quit(): 모든 작업이 끝난 후 브라우저를 닫아 리소스를 해제합니다.

다음 내용이 궁금하다면?

코드프렌즈 PLUS 멤버십 가입 or 강의를 등록해 주세요!