티스토리 뷰

반응형
1. 네이버 주식 시가총액 목록 가져오기 (https://finance.naver.com/sise/sise_market_sum.nhn)


2. 기업 별 상세 재무 데이터 가져오기 (https://finance.naver.com/item/main.nhn?code=기업코드)
  - def getDataOfParam(param)


3. Python Dictionary 사용하여 데이터 정리


4. 원하는 데이터 지표 추출 (매출액, 영업이익, 당기순이익, ROE, PER, PBR)
  - def printRecommendedItems(stock):


5. 추출 데이터 메일로 자동 전송하기
  - def sendEmailfunc(text):

의 5단계를 통해서 네이버 주식정보 가져오는 방법을 포스팅 하려고 한다. 

 

1. 네이버 주식 시가 총액 목록 가져오기

 

 네이버 증권 > 시가총액 사이트는 시가총액 순으로 한 페이지에 50개씩의 기업을 보여주고 있다. 

GET 메소드로 Page 값을 넘기고 있음

 

먼저 url request 를 위해 관련 library 를 추가하면, request 와 BeautifulSoup 를 import 한다. 

import requests
from bs4 import BeautifulSoup

HTML의 구조를 이해한다고 생각하고 포스팅을 진행한다. 혹시, HTML 구조에 대해서 댓글을 통해 문의를 하면 

포스팅이나 댓글로 충분히 이해할 수 있도록 설명을 하려고 한다.

(필요하신 분은 댓글로 남겨주세요^^)

 

Python 에서 HTML 을 분석하는 쉬운 방법 중 하나는 HTML문서 구조 분석을 위해 제공되는 BeautifulSoup 라이브러리가 있다. parser 로 lxml 을 이용해서 분석을 쉽게 해준다. 

 

간단한 코드로 예제를 보여주면, 

 

url = "https://finance.naver.com/sise/sise_market_sum.nhn?page=1"

res = requests.get(url)
soup = BeautifulSoup(res.text, 'lxml')

print (soup)

코드 실행 결과는 아래와 같이 출력된다. 우리는 이 데이터 중에서 적절한 필터를 활용하여 쉽게 접근하여 원하는 값을 얻을 수 있다. 

C:\Python38-32\python.exe "D:/naver_stock.py"
<!--  global include --><html lang="ko">
<head>
<title>시가총액 : 네이버 금융</title>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type"/>
<meta content="text/javascript" http-equiv="Content-Script-Type"/>
<meta content="text/css" http-equiv="Content-Style-Type"/>
....
....
// add data-useragent 
document.documentElement.setAttribute('data-useragent',navigator.userAgent); 
</script> 
</div> 
</body> 
</html>

구조화된 HTML 에 익숙해지려면 F12 버튼을 통해서 확인 할 수 있는 개발자모드와 익숙해져야 한다. 

시가총액 순 기업을 보여주는 표의 제목 : HTML 상 Table > thead > tr >th 구조

위 그림은 표의 헤더를 표현하는 HTML 코드이다. 

beautifulsoup 는 이러한 html 을 직관적으로 접근 할 수 있게 해준다. 

stock_head = soup.find("thead").find_all("th")
data_head = [head.get_text() for head in stock_head]

print(data_head)

코드는 soup 객체에서 "thead"를 찾고 ==> 그 하위의 모든 "th"를 찾고 있다. 

find_all 함수는 모든 "th"를 불러오기 때문에 리스트로 결과를 받아오고, for loop 를 활용하여 data_head 에 값을 불러올 수 있다. 

 

실행하면 아래와 같은 값을 출력한다. 

['N', '종목명', '현재가', '전일비', '등락률', '액면가', '시가총액', '상장주식수', '외국인비율', '거래량', 'PER', 'ROE', '토론실']

 

끝으로 동일하게 각 기업의 정보를 불러오면, 아래와 같다. 

stock_list = soup.find("table", attrs={"class": "type_2"}).find("tbody").find_all("tr")

for stock in stock_list:
     if len(stock) > 1 :
          print(stock.get_text().split())

 

class:type_2 인 table > tbody > tr 값 불러오기

먼저 html 을 잘 보면 알겠지만 우리가 가지고 오려는 table 외에 하나 더 table 이 있기 때문에 class 명으로 필터를 하여 하나의 테이블을 선택하였고, 하위의 tbody > tr 을 필터하여 기업 리스트를 불러왔다. 

 

tr 데이터를 잘 보면, 일부 tr은 UI를 위해 공백을 만드는 용도로 사용되고 있어 필터하여 stock 의 len이 1이상인 데이터만 호출했다. 

 

결과는 아래와 같다. 

(사실,,공백을 없애기 위해 replace 함수를 이용하여 '\t', '\n'을 공백으로 바꾸는 삽질을 했었지만, 마지막에 list 로 split 하니 한번에 해결되었다..삽질은..무한하다)

C:\Python38-32\python.exe "D:/naver_stock.py"
['N', '종목명', '현재가', '전일비', '등락률', '액면가', '시가총액', '상장주식수', '외국인비율', '거래량', 'PER', 'ROE', '토론실']
['1', '삼성전자', '66,300', '3,100', '+4.91%', '100', '3,957,966', '5,969,783', '56.45', '35,414,115', '20.74', '8.69']
['2', 'SK하이닉스', '98,000', '8,300', '+9.25%', '5,000', '713,442', '728,002', '49.43', '9,213,894', '31.21', '4.25']
['3', '삼성바이오로직스', '758,000', '1,000', '+0.13%', '2,500', '501,531', '66,165', '10.14', '73,598', '146.02', '4.77']
['4', '삼성전자우', '58,800', '1,400', '+2.44%', '100', '483,857', '822,887', '86.55', '4,520,731', '18.40', 'N/A']
['5', 'LG화학', '677,000', '28,000', '-3.97%', '5,000', '477,910', '70,592', '41.00', '531,111', '116.70', '1.84']
['6', 'NAVER', '278,000', '3,000', '-1.07%', '100', '456,652', '164,263', '55.71', '884,422', '64.80', '10.56']
['7', '셀트리온', '288,500', '1,500', '-0.52%', '1,000', '389,457', '134,994', '20.56', '575,881', '97.30', '11.19']
['8', '현대차', '179,000', '1,500', '+0.85%', '5,000', '382,466', '213,668', '30.84', '2,733,268', '25.79', '4.32']
['9', '삼성SDI', '485,500', '15,500', '-3.09%', '5,000', '333,852', '68,765', '43.49', '565,597', '178.36', '2.94']
['10', '카카오', '362,000', '3,500', '-0.96%', '500', '319,572', '88,280', '32.04', '555,249', '-206.86', '-5.81']
...
...
['48', 'CJ제일제당', '367,000', '500', '+0.14%', '5,000', '55,249', '15,054', '23.48', '62,306', '9.24', '3.16']
['49', '코웨이', '74,600', '1,400', '+1.91%', '500', '55,055', '73,800', '61.03', '177,553', '15.68', '30.74']
['50', 'LG디스플레이', '14,950', '200', '+1.36%', '5,000', '53,493', '357,816', '22.44', '1,915,842', '-1.84', '-22.35']

아주 간단하게 끝날 것 같았던 포스팅이...주저리주저리 2시간을 넘게 작성하고 있다. 

 


다음 포스팅에서는 각각의 기업의 상세정보를 가져오는 코드를 공유하려고 한다.

 

[PYTHON] 네이버 주식정보 가져오기 (2/4)

 

[PYTHON] 네이버 주식정보 가져오기 (2/4)

1. 네이버 주식 시가총액 목록 가져오기 (https://finance.naver.com/sise/sise_market_sum.nhn) 2. 기업 별 상세 재무 데이터 가져오기 (https://finance.naver.com/item/main.nhn?code=기업코드) - def getDat..

cocoabba.tistory.com

반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함