최초작성 : 2023.3.31
네이버 증권에서 일별 시세 정보를 가져오는 코드이다.
아래 코드로는 100% 만족된 결과를 도출하지 못한다.
IF 조건문을 사용해서 원하는 결과를 도출하는 건 개발자의 몫이다.
또한 DB에 저장되는 순서를 날짜가 적은 데이터를 먼저 저장하기 위한 방법으로 수정하는 것이 좋다.
| import requests from fake_useragent import UserAgent # BeautifulSoup은 HTML 과 XML 파일로부터 데이터를 수집하는 라이브러리 from bs4 import BeautifulSoup # BeautifulSoup 에서는 Xpath 사용 불가능 import pymysql import re def financialSiseDayData(code,page):     ua = UserAgent()     headers = {'User-agent': ua.ie}     url = f'https://finance.naver.com/item/sise_day.naver?code={code}&page={page}'     # print(url)     res = requests.get(url, headers=headers)     #     if res.status_code == 200:         html = res.text         # HTML 페이지 파싱 BeautifulSoup(HTML데이터, 파싱방법)         soup = BeautifulSoup(html, 'html.parser')         # find() : 가장 먼저 검색되는 태그 반환         body = soup.select_one("table")         # print(body)         items = body.find_all('tr', {'onmouseover':'mouseOver(this)'})         # print(items)         conn = pymysql.connect(host="localhost", user="", password="", db="studydb", charset="utf8")         curs = conn.cursor()         for item in items:             information = item.text             info = information.split('\n')             # print(info)             # print(info[2], "type: ", type(info[2]))             # print(code, info[1],info[2],info[8],info[9],info[10],info[11],info[5].strip())             closeM = re.sub(r'[^0-9]', '', info[2])             openM = re.sub(r'[^0-9]', '', info[8])             highM = re.sub(r'[^0-9]', '', info[9])             lowM = re.sub(r'[^0-9]', '', info[10])             volume = re.sub(r'[^0-9]', '', info[11])             # 기존 DB에 있는 데이터인 경우에는 중복 저장하지 말고 무시하라.             sql = "insert ignore into stock_day (code,date,close,open, high, low, volume) values (%s, %s, %s, %s, %s, %s, %s)"             val = (str(code), info[1], closeM, openM, highM, lowM, volume)             curs.execute(sql,val)             conn.commit()         conn.close()     else:         print(res.status_code) if __name__ == '__main__':     code = 140670     for i in range(1, 4): # 1개월 데이터만 추출         financialSiseDayData(code,str(i))     print('완료되었습니다.') | 
DB에 저장하기 위한 SQL 코드
| CREATE TABLE stock_day (   idx int(11) NOT NULL,   code varchar(8) NOT NULL COMMENT '종목코드',   date char(10) NOT NULL COMMENT '날짜',   close double NOT NULL DEFAULT 0 COMMENT '종가',   open double NOT NULL DEFAULT 0 COMMENT '시가',   high double NOT NULL DEFAULT 0 COMMENT '고가',  low double NOT NULL DEFAULT 0 COMMENT '저가',   volume double NOT NULL DEFAULT 0 COMMENT '거래량',   display int(2) NOT NULL DEFAULT 1,   reg_date timestamp NOT NULL DEFAULT current_timestamp() ) ENGINE=InnoDB DEFAULT CHARSET=utf8; ALTER TABLE stock_day   ADD PRIMARY KEY (idx),   ADD UNIQUE KEY code_date (code,date); ALTER TABLE stock_day   MODIFY idx int(11) NOT NULL AUTO_INCREMENT; COMMIT; | 
코드와 날짜를 UNIQUE KEY 로 설정하였다.
Updated : 2024.08.30
위 코드를 가지고 PHP simple_html_dom 라이브러리를 이용하는 코드로 변환을 시도했었다.
결과가 만족스럽지 못해서 DOM 을 분석하면서 다시 작성을 했다.
그리고 다시 ChatGTP를 이용하여 Python 코드로 변경해 달라고 했더니 좀 더 깔끔한 결과를 얻었다.
| import requests from fake_useragent import UserAgent from bs4 import BeautifulSoup import re def financialSiseDayData(code,page):     ua = UserAgent()     headers = {'User-agent': ua.ie}     url = f'https://finance.naver.com/item/sise_day.naver?code={code}&page={page}'     # print(url)     res = requests.get(url, headers=headers)     #     if res.status_code == 200:         html = res.text         # HTML 페이지 파싱 BeautifulSoup(HTML데이터, 파싱방법)         soup = BeautifulSoup(html, 'html.parser')         # table = soup.select_one(".type2")         # items = table.find_all('tr', {'onmouseover':'mouseOver(this)'})         items = soup.select('.type2 tr[onmouseover="mouseOver(this)"]')         stock_day_temp = []         for item in items:             info = []             tds = item.find_all('td')             for td in tds:                 info.append(td.get_text(strip=True))  # <td> 내부 텍스트를 추출하여 리스트에 저장             sdate = re.sub(r'[^0-9.]', '', info[0])  # 날짜             closeM = re.sub(r'[^0-9]', '', info[1])  # 종가             openM = re.sub(r'[^0-9]', '', info[3])  # 시가             highM = re.sub(r'[^0-9]', '', info[4])  # 고가             lowM = re.sub(r'[^0-9]', '', info[5])  # 저가             volume = re.sub(r'[^0-9]', '', info[6])  # 거래량             cv30 = float(closeM) * 1.3  # 상한가             cv60 = float(closeM) * 1.6  # 단기 투경 기준             cv100 = float(closeM) * 2  # 4주 투경 기준             stock_day_temp.append([                 code, sdate, closeM, openM, highM, lowM, volume, cv30, cv60, cv100             ])         for items in reversed(stock_day_temp):             print(items)     else:         print(res.status_code) if __name__ == '__main__':     code = '039610'     for i in range(1,3,1): # 1개월 데이터만 추출         financialSiseDayData(code,str(i))     print('완료되었습니다.') | 
728x90
    
    
  'Web 크롤링 > Python Crawling' 카테고리의 다른 글
| 파이썬 selenium CentOS 7 환경설정 및 juso.go.kr 자료 파싱처리 (0) | 2024.03.25 | 
|---|---|
| 파이썬 selenium 드라이버 설치 없이 사용하자. (0) | 2024.03.24 | 
| 네이버 증권 정보 크롤링 예제 1 - 상장주식수 가져오기 (0) | 2023.03.26 | 
| 파이썬 selenium 활용 네이버 뉴스 스탠드 크롤링 (0) | 2021.06.28 | 
| 파이썬 selenium 활용 다나와 제품 검색 모든 페이지 크롤링 (0) | 2021.06.28 | 
