Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

Python lxml로 웹 스크래핑 구현하기 – 야후 파이낸스 주식 데이터 추출 완벽 가이드

웹 스크래핑은 데이터 사이언스에 관심 있는 사람들뿐만 아니라 웹사이트 속 데이터를 깊이 있게 탐구하고 싶은 학생이나 학습자에게도 매력적인 분야입니다. Python은 다양한 웹 스크래핑 라이브러리를 제공하는데, 대표적인 것들은 다음과 같습니다.

  • Scrapy

  • Urllib

  • BeautifulSoup

  • Selenium

  • Python Requests

  • LXML

이 글에서는 Python의 lxml 라이브러리를 사용해 웹페이지에서 데이터를 수집하는 방법을 살펴보겠습니다. lxml은 C 언어로 작성된 libxml2 XML 파싱 라이브러리를 기반으로 만들어져 Beautiful Soup보다 빠른 처리 속도를 자랑하지만, 그만큼 일부 환경(특히 Windows)에서는 설치가 다소 까다로울 수 있다는 점을 참고하세요.

lxml 설치 및 임포트하기

lxml은 명령줄에서 pip를 통해 간단히 설치할 수 있습니다.

pip install lxml

conda 환경을 사용한다면 아래 명령어를 실행하세요.

conda install -c anaconda lxml

설치가 완료되면 HTML 문서를 파싱할 수 있도록 lxml의 html 모듈을 임포트합니다.

>>> from lxml import html

다음으로 스크래핑하려는 페이지의 소스 코드를 가져와야 합니다. 이때 python requests 라이브러리 또는 urllib 중 하나를 선택해 사용할 수 있으며, 가져온 HTML 전체를 담는 lxml HTML 요소 객체를 생성하게 됩니다. 여기서는 requests 라이브러리를 사용해 페이지의 HTML 콘텐츠를 다운로드하겠습니다.

requests 라이브러리가 아직 설치되어 있지 않다면 터미널에서 아래 명령어로 간단히 설치할 수 있습니다.

$ pipenv install requests

야후 파이낸스에서 주식 데이터 스크래핑하기

예를 들어 yahoo.finance에서 주식 데이터를 수집하고 싶다고 가정해 보겠습니다. 아래는 야후 파이낸스에 등록된 마이크로소프트(Microsoft Corporation) 정보 화면입니다.

Python lxml로 웹 스크래핑 구현하기 – 야후 파이낸스 주식 데이터 추출 완벽 가이드

위 페이지(https://finance.yahoo.com/quote/msft)에서 확인할 수 있는 주식 정보 항목들을 모두 추출해 보겠습니다.

  • 전일 종가(Previous Close), 시가(Open), 매수호가(Bid), 매도호가(Ask), 일중 변동폭(Day's Range), 52주 변동폭(52 Week Range), 거래량(Volume) 등

다음은 Python lxml 모듈을 사용해 이 작업을 수행하는 전체 코드입니다.

lxml_scrape3.py

from lxml import html
import requests
from time import sleep
import json
import argparse
from collections import OrderedDict

def parse(ticker):
    url = "https://finance.yahoo.com/quote/%s?p=%s" % (ticker, ticker)
    response = requests.get(url, verify=False)
    print("Parsing %s" % (url))
    sleep(4)
    parser = html.fromstring(response.text)
    summary_table = parser.xpath('//div[contains(@data-test,"summary-table")]//tr')
    summary_data = OrderedDict()
    other_details_json_link = "https://query2.finance.yahoo.com/v10/finance/quoteSummary/{0}?formatted=true&lang=en-US&region=US&modules=summaryProfile%2CfinancialData%2CrecommendationTrend%2CupgradeDowngradeHistory%2Cearnings%2CdefaultKeyStatistics%2CcalendarEvents&corsDomain=finance.yahoo.com".format(ticker)
    summary_json_response = requests.get(other_details_json_link)
    try:
        json_loaded_summary = json.loads(summary_json_response.text)
        y_Target_Est = json_loaded_summary["quoteSummary"]["result"][0]["financialData"]["targetMeanPrice"]['raw']
        earnings_list = json_loaded_summary["quoteSummary"]["result"][0]["calendarEvents"]['earnings']
        eps = json_loaded_summary["quoteSummary"]["result"][0]["defaultKeyStatistics"]["trailingEps"]['raw']

        datelist = []
        for i in earnings_list['earningsDate']:
            datelist.append(i['fmt'])
        earnings_date = ' to '.join(datelist)
        for table_data in summary_table:
            raw_table_key = table_data.xpath('.//td[contains(@class,"C(black)")]//text()')
            raw_table_value = table_data.xpath('.//td[contains(@class,"Ta(end)")]//text()')
            table_key = ''.join(raw_table_key).strip()
            table_value = ''.join(raw_table_value).strip()
            summary_data.update({table_key: table_value})
        summary_data.update({'1y Target Est': y_Target_Est, 'EPS (TTM)': eps, 'Earnings Date': earnings_date, 'ticker': ticker, 'url': url})
        return summary_data
    except:
        print("Failed to parse json response")
        return {"error": "Failed to parse json response"}

if __name__ == "__main__":
    argparser = argparse.ArgumentParser()
    argparser.add_argument('ticker', help='')
    args = argparser.parse_args()
    ticker = args.ticker
    print("Fetching data for %s" % (ticker))
    scraped_data = parse(ticker)
    print("Writing data to output file")
    with open('%s-summary.json' % (ticker), 'w') as fp:
        json.dump(scraped_data, fp, indent=4)

위 코드를 실행하려면 명령 터미널에 아래와 같이 입력하기만 하면 됩니다.

c:\Python\Python361>python lxml_scrape3.py MSFT

lxml_scrape3.py를 실행하면 현재 작업 디렉터리에 "종목명-summary.json" 형태의 .json 파일이 자동으로 생성됩니다. 이 예제에서는 야후 파이낸스에서 MSFT(마이크로소프트) 데이터를 추출했기 때문에 "msft-summary.json"이라는 이름의 파일이 만들어집니다.

아래는 실제로 생성된 출력 파일의 모습입니다.

Python lxml로 웹 스크래핑 구현하기 – 야후 파이낸스 주식 데이터 추출 완벽 가이드

이처럼 lxml과 requests 라이브러리를 함께 활용하면 야후 파이낸스에서 마이크로소프트의 주식 데이터를 성공적으로 스크래핑할 수 있습니다. 저장된 JSON 파일은 이후 주가 변동 분석, 데이터 공유, 추가 통계 처리 등 다양한 용도로 손쉽게 재활용할 수 있다는 점이 큰 장점입니다.