DevSSOM

파이썬 크롤링 실습 - Daum 증권 페이지에서 주가 크롤링 본문

Python/크롤링

파이썬 크롤링 실습 - Daum 증권 페이지에서 주가 크롤링

데브쏨 2021. 7. 17. 23:40
반응형

Daum 증권 페이지에서 주가 크롤링

Daum 증권 페이지 http://finance.daum.net/ 에서 보여주는 인기 검색 상위 10개 기업의 결과는, 이전처럼 HTML 문서를 분석하여 크롤링하는 방식을 사용할 수 없음. 웹 페이지가 API로부터 실시간으로 변하는 주식의 정보를 주기적으로 요청하여 표시하고 있기 때문.

그래서 웹에서 요청하는 서버에 직접 요청하여 json 데이터를 얻은 후 출력해보기. API의 URL은 개발자 도구의 Network 탭에서 얻을 수 있음.

 

출력 예시

(1, '삼성전자', 54500)
(2, '삼성중공업', 6970)
...

해야할 것

get_data 함수를 올바르게 구현하기.

  • get_data : json 파일로부터 원하는 데이터를 추출한 리스트를 반환합니다.

json 파일을 파이썬 코드에서 불러오기 위해 파이썬의 json 모듈을 사용할 수 있습니다.

stock.json이라는 json 데이터를 data 변수에 로드하는 코드입니다.

import json
with open("stock.json") as stock :
    data = json.loads(stock) 
import requests
import json

custom_header = {
    'referer' : 'http://http://finance.daum.net/quotes/A048410#home',
    'user-agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'  }


def get_data() :
    result = []
    url = "" # 상위 10개 기업의 정보를 얻는 API url을 작성
    req = requests.get(url, headers = custom_header)
    
    if req.status_code == requests.codes.ok:    
        print("접속 성공")
        # API에 접속에 성공하였을 때의 logic을 작성
        # JSON 데이터의 원하는 부분만 불러와 result에 저장
        
        
    else:
        print("접속 실패")
    
    return result

def main() :
    data = get_data()
    
    for d in data :
        print(d)
    
if __name__ == "__main__" :
    main()

 

 

 

>>>

 

daum 금융으로 들어가면 보이는 인기 검색 분야가 나오는데, 이부분을 크롤링 해보기. 크롬 개발자도구로 들어가서 Network탭으로 간 뒤에 새로고침을 해보면, 웹페이지가 로딩될 때 외부에서 불러와지는 데이터가 주르륵 뜨게 됨.

 

이 상태에서 상단에 돋보기 search 버튼을 눌러주고, 우리가 검색하고자 하는 데이터인 인기 검색에서 랭크 1위로 되어있는 종목인 '카카오'를 검색. 그럼 필터링이 되는데, 그 중에서도 ranks가 우리가 찾던 항목임을 확인.

그래서 다시 ranks로 검색을 해보면 이렇게 우리가 관심있는 데이터가 불러와짐. data라는 이름의 칼럼에 여러개의 리스트가 있고, 하나의 요소는 rank와 name과 tradePrice로 순위, 종목이름, 주가가 보여짐.

그래서 이 API의 URL을 얻을거야. ranks 어쩌구를 더블클릭하면 새 창이 뜨고, 거기서 url을 가져오면 됨. 가져온 URL =  https://finance.daum.net/api/search/ranks?limit=10  이걸 get_data() 함수 안의 url에다가 복붙해서 넣어줘. 그럼 if문에서 이 requests가 실패인지, 성공인지에 따라 결과를 알려주는데, print(req.text)를 입력해서 접속결과를 한번 출력해보면

def get_data() :
    result = []
    url = "https://finance.daum.net/api/search/ranks?limit=10" # 상위 10개 기업의 정보를 얻는 API url을 작성
    req = requests.get(url, headers = custom_header)
    
    if req.status_code == requests.codes.ok:    
        print("접속 성공")
        print(req.text)
        # API에 접속에 성공하였을 때의 logic을 작성
        # JSON 데이터의 원하는 부분만 불러와 result에 저장
        
        
    else:
        print("접속 실패")
    
    return result

이렇게 데이터들을 얻을 수 있음. data라는 이름의 key로 리스트가 하나 들어있는걸 확인. 그럼 이제 우리가 원하는 정보들만 출력시키기 위해서, 비어있는 result 리스트가 위쪽에 선언되어 있으니까, result에 정보를 하나씩 넣어줄거야.

def get_data() :
    result = []
    url = "https://finance.daum.net/api/search/ranks?limit=10" # 상위 10개 기업의 정보를 얻는 API url을 작성
    req = requests.get(url, headers = custom_header)
    
    if req.status_code == requests.codes.ok:    
        print("접속 성공")
        # API에 접속에 성공하였을 때의 logic을 작성
        # JSON 데이터의 원하는 부분만 불러와 result에 저장
        stock_data = json.loads(req.text)
        print(stock_data)
        
    else:
        print("접속 실패")
    
    return result

stock_data라는 변수를 만들고 json 데이터를 로드해줄거야. json모듈에 loads()라는 메소드를 이용. 그리고 req.text를 입력하게 되면 아까와 유사한 출력 결과가 나옴.

 

이 상태에서 인덱싱을 통해서 각각의 요소를 출력할거야.

def get_data() :
    result = []
    url = "https://finance.daum.net/api/search/ranks?limit=10" # 상위 10개 기업의 정보를 얻는 API url을 작성
    req = requests.get(url, headers = custom_header)
    
    if req.status_code == requests.codes.ok:    
        print("접속 성공")
        # API에 접속에 성공하였을 때의 logic을 작성
        # JSON 데이터의 원하는 부분만 불러와 result에 저장
        stock_data = json.loads(req.text)
        
        for d in stock_data["data"] :
            print(d)
        
    else:
        print("접속 실패")
    
    return result

 

그러면 딕셔너리가 나타나게 됨. 그래서 이 d에서 필요한 부분만 필터링해서 가져올 수 있도록 해주면

def get_data() :
    result = []
    url = "https://finance.daum.net/api/search/ranks?limit=10" # 상위 10개 기업의 정보를 얻는 API url을 작성
    req = requests.get(url, headers = custom_header)
    
    if req.status_code == requests.codes.ok:    
        print("접속 성공")
        # API에 접속에 성공하였을 때의 logic을 작성
        # JSON 데이터의 원하는 부분만 불러와 result에 저장
        stock_data = json.loads(req.text)
        
        for d in stock_data["data"] :
            print(d["rank"], d["name"], d["tradePrice"])
        
    else:
        print("접속 실패")
    
    return result

이렇게 순위와 종목이름, 주가정보가 나타나게 됨.

 

이걸 한번에 묶어서 result에 리스트 형식으로 넣어주면, get_data라는 함수가 result 변수를 반환하고 

def get_data() :
    result = []
    url = "https://finance.daum.net/api/search/ranks?limit=10" # 상위 10개 기업의 정보를 얻는 API url을 작성
    req = requests.get(url, headers = custom_header)
    
    if req.status_code == requests.codes.ok:    
        print("접속 성공")
        # API에 접속에 성공하였을 때의 logic을 작성
        # JSON 데이터의 원하는 부분만 불러와 result에 저장
        stock_data = json.loads(req.text)
        
        for d in stock_data["data"] :
            result.append([d["rank"], d["name"], d["tradePrice"]])
        
    else:
        print("접속 실패")
    
    return result

 

 

 

최종 코드

import requests
import json

custom_header = {
    'referer' : 'http://http://finance.daum.net/quotes/A048410#home',
    'user-agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'  }


def get_data() :
    result = []
    url = "https://finance.daum.net/api/search/ranks?limit=10" # 상위 10개 기업의 정보를 얻는 API url을 작성
    req = requests.get(url, headers = custom_header)
    
    if req.status_code == requests.codes.ok:    
        print("접속 성공")
        # API에 접속에 성공하였을 때의 logic을 작성
        # JSON 데이터의 원하는 부분만 불러와 result에 저장
        stock_data = json.loads(req.text)
        
        for d in stock_data["data"]:
            result.append([d['rank'], d['name'], d['tradePrice']])
        
    else:
        print("접속 실패")
    
    return result

def main() :
    data = get_data()
    
    for d in data :
        print(d)
    
if __name__ == "__main__" :
    main()

 

 

 

728x90
반응형
댓글