본문 바로가기
Python/Python 자동화

pyqt selenium 채권 정보 크롤링 (3): python활용한 채권 데이터 크롤링 구현

by 고독한석사생 2023. 7. 3.

라이브러리 불러오기

from selenium import webdriver
from selenium.webdriver.chrome.options import Options # 옵션
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys

import requests
from bs4 import BeautifulSoup

import pandas as pd

셀레니움 사용을 위해 selenium 및 request 등 관련 라이브러리를 불러옵니다.

 

구현은 크롬 환경에서 진행합니다.


크롬 창 원격제어

url = 'https://www.shinhansec.com/siw/wealth-management/bond-rp/590401/view.do'

# 브라우저 생성
options = Options()
# options.add_argument("--headless") # 크롬 안띄우기
options.add_experimental_option('excludeSwitches',['enable-logging']) # 불필요한 메시지 제거


service = Service(ChromeDriverManager(path="C:/Driver").install())
browser = webdriver.Chrome(service=service, options=options)

# 웹사이트 열기
browser.get(url)
browser.implicitly_wait(5) # 로딩 5초까지는 기다림
time.sleep(10)

신한투자증권의 장내채권시세 창을 url 변수로 할당합니다.

 

셀레니움 라이브러리가 업데이트 되면서 기능이 간편해졌는데, 

크롬드라이버를 따로 설치해주지 않아도, Service(ChromeDriverManager(path).install())를 통해서 자동으로 해당 경로에 설치하고, 크롬 버전에 따라 업데이트 해주게 됩니다.

 

browser를 설정한 뒤, url를 인풋으로 주어 해당 주소 창을 띄웁니다.

browser.implicitly_wait를 통해 사이트 로딩 시간을 기다립니다.

 

 

채권 테이블 스크롤 맨 아래까지 내리기

# 무한 스크롤
table_element = browser.find_element(By.CSS_SELECTOR, "div.tableScroll")
before_h = browser.execute_script("return arguments[0].scrollTop;", table_element)

while True:
    browser.find_element(By.CSS_SELECTOR, "div.tableScroll").send_keys(Keys.END) # 내린다
    after_h = browser.execute_script("return arguments[0].scrollTop;", table_element) # 내린 높이를 저장

    # 이전과 같으면 그만둔다
    if before_h==after_h:
        break
    before_h = after_h # 업데이트

table_element에 채권 테이블 CSS를 설정합니다.

 

해당 테이블의 스크롤 높이를 before_h라는 변수에 초기 할당합니다.

 

while문 설명)

1. browser.find_element(By.CSS_SELECTOR, "div.tableScroll").send_keys(Keys.END) # 내린다

: 테이블 스크롤을 현재 가능한 수준에서 맨 아래까지 내린다

-> 인스타그램 게시글이나 유튜브 댓글에서 스크롤을 내리면 새로운 항목이 불러와지는 것처럼 스크롤이 더 생기게 됩니다.

 

 2. after_h = browser.execute_script("return arguments[0].scrollTop;", table_element) # 내린 높이를 저장

: 내린 후, 스크롤 높이를 after_h 변수에 할당합니다.

-> 우리는 이전 스크롤 높이와 내린 뒤 스크롤 높이를 비교해 변동이 없으면 테이블 맨 밑까지 왔음을 유추할 수 있습니다.

 

3. 이전 스크롤 높이와 현재 스크롤 높이가 같으면 멈추고, 아니면 이전 스크롤 높이를 현재 높이로 업데이트 한 뒤, 다시 내리고 비교를 반복합니다.

 

 

# 이름 파싱
names = browser.find_elements(By.CSS_SELECTOR, 'td.t_left')
current_prices = browser.find_elements(By.CSS_SELECTOR, 'td:nth-child(3)')
volumes = browser.find_elements(By.CSS_SELECTOR, 'td:nth-child(5)')
Returns = browser.find_elements(By.CSS_SELECTOR, 'td:nth-child(7)')


name_list=[]
current_price_list=[] 
volume_list=[]
Return_list=[]
for i in tqdm(range(len(names))):
    name = names[i].find_element(By.CSS_SELECTOR, 'span').text
    name_list.append(name)

    current_price = current_prices[i].find_element(By.CSS_SELECTOR, 'span').text
    current_price_list.append(current_price)

    volume = volumes[i].text
    volume_list.append(volume)

    Return = Returns[i].find_element(By.CSS_SELECTOR, 'span').text
    Return_list.append(Return)

browser.quit() # 닫기


df = pd.DataFrame(zip(name_list,current_price_list,volume_list,Return_list), columns=['name','price','volume','Return'])
df['price'] = df['price'].apply(lambda x: x.replace(',',''))
df['volume'] = df['volume'].apply(lambda x: x.replace(',',''))
df['Return'] = df['Return'].apply(lambda x: x.replace(',',''))

df['price'] = df['price'].astype(float) # 현재가
df['volume'] = df['volume'].astype(float) # 거래량
df['Return'] = df['Return'].astype(float) # 수익률

테이블 스크롤이 다 내려갔으므로, 테이블 내 채권 아이템들은 다 보이게 됩니다.

 

그 말은 모든 요소 정보를 긁어올 수 있다는 말인데,

 

이름, 현재가격, 거래량, 수익률 전체 정보를 가져옵니다.

 

그리고 for문을 통해 각 정보를 돌면서 적혀진 글자를 가져옵니다.

 

이제 크롤링이 다 끝났으므로, browser.quit()을 통해 제어 중인 크롬 창을 닫습니다.

 

추출된 정보를 pandas DataFrame으로 만들었습니다.

 

반응형