파이썬으로 Google Finance 스크래핑하는 방법

Python과 BeautifulSoup을 활용해 Google Finance 스크래핑을 마스터하여 가치 있는 시장 데이터를 추출하거나, 미리 준비된 데이터셋으로 시간을 절약하세요.
4 분 읽기
How to Scrape Google Finance blog image

모든 데이터는 가치 있습니다. 집계 데이터는 웹에서 가장 수요가 많은 유형 중 하나입니다. Google Finance에는 다양한 금융 시장에 대한 방대한 집계 데이터가 포함되어 있습니다. 이 데이터는 트레이딩 봇부터 일반 보고서까지 모든 용도로 유용합니다.

시작해 보겠습니다!

필수 조건

적절한 기술만 있다면 Google Finance에서 데이터를 비교적 쉽게 추출할 수 있습니다. Google Finance 스크래핑을 위해서는 다음이 필요합니다.

  • 파이썬: 파이썬에 대한 기본적인 이해만 있으면 됩니다. 변수, 함수, 루프를 다루는 방법을 알아야 합니다.
  • Python Requests: 표준 Python HTTP 클라이언트입니다. 웹 전반에서 GET, POST, PUT, DELETE 요청을 수행하는 데 사용됩니다.
  • BeautifulSoup: BeautifulSoup은 효율적인 HTML 파서를 제공합니다. 데이터를 추출하는 데 사용됩니다.

아직 설치하지 않았다면 다음 명령어로 Requests와 BeautifulSoup을 설치할 수 있습니다.

Requests 설치

pip install requests

BeautifulSoup 설치

pip install beautifulsoup4

Google Finance에서 스크래핑할 내용

구글 파이낸스 메인 페이지의 모습입니다. 여기에는 다양한 시장에 대한 작은 정보 조각들이 포함되어 있습니다. 우리는 작은 조각이 아닌 여러 시장에 대한 상세한 정보를 원합니다.

Google Finance full page

조금만 아래로 스크롤하면 페이지 오른쪽에 ‘시장 동향(Market trends) ‘ 섹션이 보입니다. 이 섹션의 각 버블은 특정 시장에 대한 상세 정보로 연결됩니다. 우리가 관심 있는 시장은 다음과 같습니다: 상승주(Gainers), 하락주(Losers), 시장 지수(Market indexes), 가장 활발한 종목(Most active), 암호화폐(Crypto).

Main market trends

이제 각 페이지를 클릭하여 살펴보겠습니다. 상승 종목부터 시작하겠습니다. 주소 표시줄에서 확인할 수 있듯이, URL은 다음과 같습니다: https://www.google.com/finance/markets/gainers. 하단의 개발자 콘솔을 보면 전체 데이터 세트가 ul( 무순서 목록)에 포함되어 있음을 알 수 있습니다.

Inspecting the gainers

이제 하락 종목을 살펴보겠습니다. 해당 URL은 다음과 같습니다: https://www.google.com/finance/markets/losers. 다시 한번, 데이터 세트가 무순서 목록에 포함되어 있음을 확인할 수 있습니다.

Inspecting the losers

시장 지수 페이지의 동일한 화면입니다. 이 페이지는 약간 특별합니다. 여러 개의 ul 요소를 포함하고 있으므로 코드에서 이를 처리해야 합니다. URL은 https://www.google.com/finance/markets/indexes입니다. 패턴이 보이기 시작하시나요?

Inspecting the market indexes page
Inspecting the market indexes page 2

가장 활발한 페이지가 아래에 표시됩니다. 다시 한번, 모든 대상 데이터가 ul 안에 포함되어 있습니다. URL은 다음과 같습니다: https://www.google.com/finance/markets/most-active.

Inspecting the most active page

마지막으로 암호화폐 페이지를 살펴보겠습니다. 예상하셨겠지만, 데이터는 ul 안에 있습니다. URL은 다음과 같습니다: https://www.google.com/finance/markets/cryptocurrencies.

Inspecting the crypto page

이들 각 페이지에서 대상 데이터는 정렬되지 않은 목록에 포함되어 있습니다. 데이터를 추출하려면 이러한 ul 요소를 찾아 각각에서 li (목록 항목) 요소를 추출해야 합니다. 기본 URL을 살펴보세요: https://www.google.com/finance/markets. 각 페이지는 markets 엔드포인트에서 제공됩니다. URL 형식은 다음과 같습니다: https://www.google.com/finance/markets/{시장명}. 5개의 데이터셋과 5개의 URL이 모두 동일한 구조로 되어 있습니다. 이로 인해 몇 가지 변수만으로도 대량의 데이터를 쉽게 스크래핑할 수 있습니다.


Python으로 Google Finance 수동 스크래핑하기

차단을 피할 수 있다면 Python Requests와 BeautifulSoup을 사용해 Google Finance를 스크래핑할 수 있습니다. 데이터를 스크래핑할 수 있어야 하며 저장할 수 있어야 합니다. 다양한 엔드포인트가 있지만 모두 동일한 기본 URL( https://google.com/finance/markets/)에서 파생됩니다. 페이지를 가져올 때마다 ul 요소를 찾아 각 목록에서 모든 li 요소를 추출해야 합니다.

스크립트에서 사용할 기본 함수를 살펴보겠습니다. write_to_csv()scrape_page()라고 명명했습니다. 이름만 봐도 용도가 명확합니다.

개별 함수

write_to_csv() 함수를 살펴보겠습니다.

def write_to_csv(data, filename):
    if type(data) != list:
        data = [data]
    print("CSV에 기록 중...")
    filename = f"google-finance-{filename}.csv"
    mode = "w"
    if Path(filename).exists():
        mode = "a"
    print("CSV 파일에 데이터 쓰기 중...")
    with open(filename, mode) as file:
        writer = csv.DictWriter(file, fieldnames=data[0].keys())
        if mode == "w":
            writer.writeheader()
        writer.writerows(data)
    print(f"CSV에 {filename} 성공적으로 작성...")
  • 우리 함수는 딕셔너리 객체 목록을 CSV에 기록해야 합니다. 데이터가 리스트가 아닌 경우 data = [data]로 변환합니다.
  • 생성하는 각 파일은 Google Finance에서 가져온 것이므로 파일 생성 시 해당 정보를 추가합니다: filename = f"google-finance-{filename}.csv".
  • 기본 모드는 "w" (쓰기)이지만, 파일이 존재할 경우 모드를 "a" (추가)로 변경합니다.
  • csv.DictWriter(file, fieldnames=data[0].keys()) 로 파일 라이터를 초기화합니다.
  • 쓰기 모드에서는 파일이 아직 존재하지 않으므로, 리스트의번째 딕셔너리에서 헤더를 생성합니다.
  • 설정이 완료되면 writer.writerows(data)로 데이터를 파일에 추가합니다.

이제 실제 스크래핑 함수인 scrape_page()를 살펴보겠습니다. 여기서 진짜 마법이 일어납니다. 포맷된 URL로 요청을 보냅니다. 그런 다음 BeautifulSoup을 사용하여 수신된 HTML을 파싱합니다. 추출된 데이터를 담을 빈 리스트 scraped_data를 생성합니다. 페이지의 모든 ul 요소를 찾습니다. 그런 다음 찾은ul에서 li 요소를 추출합니다. 하지만 문제가 있습니다. 각 목록 항목의 텍스트는 여러 div 요소 안에 중첩되어 있습니다. 스크랩한 실제 배열에는 중복된 항목이 많이 포함됩니다. 이를 해결하기 위해 3번째, 6번째, 8번째, 11번째 항목을 추출하여 scraped_data에 append()로 추가합니다.

scrape_page() 함수는 아래 스니펫에 있습니다.

def scrape_page(endpoint: str):
    response = requests.get(f"https://google.com/finance/markets/{endpoint}")
    soup = BeautifulSoup(response.text, "html.parser")
    tables = soup.find_all("ul")
    scraped_data = []
    for table in tables:
    list_elements = table.find_all("li")
    for list_element in list_elements:

            divs = list_element.find_all("div")
            asset = {
                "ticker": divs[3].text,
                "name": divs[6].text,
                "currency": divs[8].text[0] if endpoint != "cryptocurrencies" else "n/a",
                "price": divs[8].text,
                "change": divs[11].text
            }
            scraped_data.append(asset)
    write_to_csv(scraped_data, endpoint)
  • 이 엔드포인트로 GET 요청을 수행합니다: requests.get(f"https://google.com/finance/markets/{endpoint}").
  • 응답에 BeautifulSoup의 HTML 파서를 사용합니다: soup = BeautifulSoup(response.text, "html.parser").
  • 페이지의 모든 테이블을 찾습니다: tables = soup.find_all("ul").
  • scraped_data = [] 결과물을 담을 배열을 생성합니다.
  • 찾은 각 테이블을 반복하며 다음 작업을 수행합니다: “
    • 모든 목록 항목을 찾습니다: table.find_all("li").
    • 각 리스트 항목을 반복하며 해당 div 요소를 찾습니다. 이 작업은 divs라는 리스트를 반환합니다.
    • divs에서 3, 6, 8, 11번째 항목의 텍스트를 추출하여 딕셔너리를 만듭니다.
    • 딕셔너리를 scraped_data에 추가합니다.
    • 암호화폐 가격은 거래 쌍에 따라 결정되므로, 암호화폐 엔드포인트에 있을 경우 통화를 '해당 없음(n/a)‘으로 재설정합니다.
  • 페이지 파싱이 완료되면 scraped_data를 CSV로 저장합니다: write_to_csv(scraped_data, endpoint). 엔드포인트를 파일명으로 전달합니다.

Google Finance 데이터 스크래핑

위 함수들을 스크립트로 통합하여 전체 기능을 구현합니다. 해당 함수들 외에도 엔드포인트 목록을 추가합니다. 런타임을 관리할 메인 함수도 추가합니다. 아래 코드를 복사하여 실행해 보세요!

import requests
from bs4 import BeautifulSoup
import csv
from pathlib import Path



endpoints = ["gainers", "losers", "indexes", "most-active", "cryptocurrencies"]

def write_to_csv(data, filename):
    if type(data) != list:
        data = [data]
    print("CSV에 쓰기 중...")
    filename = f"google-finance-{filename}.csv"
    mode = "w"
    if Path(filename).exists():
        mode = "a"
    print("CSV 파일에 데이터 쓰기 중...")
    with open(filename, mode) as file:
        writer = csv.DictWriter(file, fieldnames=data[0].keys())
        if mode == "w":
            writer.writeheader()
        writer.writerows(data)
    print(f"CSV에 {filename} 성공적으로 작성...")


def scrape_page(endpoint: str):
    response = requests.get(f"https://google.com/finance/markets/{endpoint}")
    soup = BeautifulSoup(response.text, "html.parser")
    tables = soup.find_all("ul")
    scraped_data = []
    for table in tables:
    list_elements = table.find_all("li")
    for list_element in list_elements:

            divs = list_element.find_all("div")
            asset = {
                "ticker": divs[3].text,
                "name": divs[6].text,
                "currency": divs[8].text[0] if endpoint != "cryptocurrencies" else "n/a",
                "price": divs[8].text,
                "change": divs[11].text
            }
            scraped_data.append(asset)
    write_to_csv(scraped_data, endpoint)



if __name__ == "__main__":
    
    for endpoint in endpoints:
        print("---------------------")
        scrape_page(endpoint) 

위 코드를 실행하면 다음과 같은 출력이 나타납니다.

---------------------
CSV에 쓰기 중...
CSV 파일에 데이터 쓰기 중...
google-finance-gainers.csv를 CSV에 성공적으로 작성했습니다...
---------------------
CSV에 쓰기 중...
CSV 파일에 데이터 쓰기 중...
google-finance-losers.csv를 CSV에 성공적으로 작성했습니다...
---------------------
CSV에 쓰기 중...
CSV 파일에 데이터 쓰기 중...
google-finance-indexes.csv를 CSV에 성공적으로 작성했습니다...
---------------------
CSV에 쓰기 중...
CSV 파일에 데이터 쓰기 중...
google-finance-most-active.csv를 CSV에 성공적으로 작성했습니다...
---------------------
CSV에 작성 중...
CSV 파일에 데이터 작성 중...
google-finance-cryptocurrencies.csv를 CSV에 성공적으로 작성했습니다...

VSCode로 스크립트를 실행하면 스크레이퍼 작업 완료 시 CSV 파일이 생성되는 것을 직접 확인할 수 있습니다. 아래 스크린샷에서 해당 파일이 강조 표시되어 있습니다.

The CSV files on VSCode

각 파일이 ONLYOFFICE에서 어떻게 보이는지 스크린샷도 보여드리겠습니다.

가장 활발한 종목

Most active CSV

가장 큰 하락 종목

Losers CSV

지수

Indexes CSV

상승 종목

Gainers CSV

암호화폐

Crypto CSV

고급 기술

페이지 처리

전통적으로 페이지 매김은 숫자를 사용하여 처리됩니다. Google Finance의 경우, 실제로 엔드포인트 배열을 사용하여 페이지 매김을 처리합니다. 엔드포인트 목록의 각 항목은 스크래핑하려는 개별 페이지를 나타냅니다. 이 목록을 다시 살펴보세요. 웹 스크래핑 시 페이지 매김 처리 방법에 대한 자세한 내용은 여기에서 확인하세요.

endpoints = ["gainers", "losers", "indexes", "most-active", "cryptocurrencies"]

이제 실제 사용 방식을 살펴보겠습니다. 기존 페이지네이션 방식에서는 숫자를 전달할 엔드포인트나 쿼리 매개변수를 사용합니다. 그러나 이 스크레이퍼에서는 각 페이지의 엔드포인트를 기본 URL에 직접 전달합니다.

response = requests.get(f"https://google.com/finance/markets/{endpoint}")

차단 방지

테스트 중에는 차단 문제를 겪지 않았습니다. 하지만 세상은 완벽하지 않으며, 향후 차단에 직면할 가능성도 있습니다. 발생할 수 있는 차단을 우회하기 위해 사용할 수 있는 다양한 방법이 있습니다.

가짜 사용자 에이전트

웹사이트에 요청을 보낼 때(브라우저나 Python Requests를 사용하든), HTTP 클라이언트는 사용자 에이전트 문자열을 사이트 서버로 전송합니다. 이는 요청을 보내는 애플리케이션을 식별하는 데 사용됩니다. Python에서 가짜 사용자 에이전트를 설정하려면 사용자 에이전트 문자열을 생성한 후 헤더에 추가합니다.

USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"

headers = {
    "User-Agent": USER_AGENT
}

response = requests.get(f"https://google.com/finance/markets/{endpoint}", headers=headers)

시간 제한 요청

요청 시간 조절은 매우 효과적입니다. 분당 200페이지를 요청하는 것은 인간이 아닐 가능성이 높습니다. 속도 제한을 우회하고 더 인간처럼 보이게 하려면 스크레이퍼가 요청 사이에 대기하도록 설정할 수 있습니다. 이렇게 하면 브라우징 활동이 훨씬 더 정상적으로 보입니다. 먼저 time 모듈에서 sleep 함수를 임포트해야 합니다.

from time import sleep

다음으로, 요청 사이에 임의의 시간 동안 대기합니다. 이렇게 하면 스크레이퍼 속도가 느려져 더 인간적인 모습을 보일 수 있습니다.

response = requests.get(f"https://google.com/finance/markets/{endpoint}")
sleep(5)

Bright Data 사용 고려하기

웹 스크래핑은 상당한 작업이 될 수 있습니다. Bright Data는 최고의 데이터셋 제공업체 중 하나입니다. 저희 데이터셋을 사용하면 스크래핑 작업이 이미 완료되어 보고서를 바로 활용할 수 있습니다. 여러분이 해야 할 일은 다운로드하는 것뿐입니다. 웹 스크래핑이 모든 사람에게 적합한 것은 아니며, 단순히 데이터를 얻어 활용하려는 분들도 있다는 점을 잘 알고 있습니다.

Google Finance 데이터셋은 제공하지 않지만 Yahoo Finance 데이터셋을 보유하고 있습니다. Yahoo Finance는 실제로 더 광범위한 금융 데이터를 제공하며 Google Finance의 요구 사항을 쉽게 충족시킬 수 있습니다. 아래에서 이 데이터셋을 구매하는 방법을 안내해 드리겠습니다.

계정 생성

먼저 계정을 생성해야 합니다. 저희 등록 페이지로 이동하여 계정을 생성하세요.

Creating a new Bright Data account

Bright Data 데이터셋 다운로드

다음으로 금융 데이터셋 페이지로 이동하세요. 야후 파이낸스 데이터셋을 찾아 ‘데이터셋 보기’ 버튼을 클릭하세요.

Searching the dataset marketplace

데이터셋을 확인하면 몇 가지 옵션이 제공됩니다. 샘플 데이터셋을 다운로드하거나 데이터셋을 구매할 수 있습니다. 레코드당 $0.0025이며 최소 구매 금액은 $500입니다. 데이터셋을 원하시면 ‘구매 진행’을 클릭하고 결제 절차를 완료하세요.

Viewing the dataset you chose

사전 제작된 데이터셋의 경우 스크래핑 작업이 이미 완료되어 있습니다. 데이터를 받아 바로 업무를 진행하시면 됩니다!

결론

완료하셨습니다! 집계 데이터는 전 세계 사람들에게 매우 유용한 도구입니다. 이제 Google Finance에서 데이터를 스크래핑하는 방법과 저희 Yahoo Finance 데이터셋에서 데이터를 얻는 방법을 알게 되셨습니다! 지금까지 Python Requests와 BeautifulSoup을 사용해 기본 스크래퍼를 만드는 방법을 익히셨을 것입니다. BeautifulSoup으로 페이지 객체를 파싱할find_all() 메서드를 사용하는 방법도 알게 되셨을 것입니다.

엔드포인트를 활용한 페이지네이션 처리나 차단 기술 완화 같은 고급 기법도 살펴봤습니다. 이 지식을 바탕으로 스크래퍼를 직접 구축하거나, 저희의 즉시 사용 가능한 데이터셋을 다운로드해 시간과 노력을 절약해 보세요.

지금 가입하시면 무료 체험을 시작하실 수 있으며, 무료 데이터셋 샘플도 포함됩니다.