주식 일별 시세 >> dataframe으로 결합하기
다음과 같은 종목별 일별 시세 내용을 데이터 프레임으로 저장할 수 있도록 크롤링 해보자
1. 라이브러리 import
import requests
from bs4 import BeautifulSoup
import pandas as pd
from fake_useragent import UserAgent
2. 데이터를 가져올 수 있는 함수 정의
🔎 getData()
- 함수의 입력 파라미터는 다음과 같다
- url: 데이터를 스크래핑할 웹 페이지의 URL
- com_code: 크롤링할 종목코드
- soup: (다른 함수에서 return 할 값, 다른 함수 참고)
- page: 스크래핑할 페이지 수 (예, 1 페이지부터 ~ 10페이지까지 크롤링할 경우 >> 10)
- df 와 count 변수를 초기화하고 시작
- df : 크롤링한 데이터를 저장하기 위한 데이터프레임 (처음엔 아무것도 없으니 none)
- count : 원하는 페이지까지 크롤링하기 위해 설정(여기서는 10페이지까지 크롤링할 예정)
- f'{url}&page={page}': 문자열 포매팅을 사용하여 요청할 URL을 구성
- url은 웹 페이지의 기본 URL이며, page는 요청할 페이지 번호
- age 변수의 값을 해당 URL에 포함시킨 형태로 요청을 보내게 됨
- 기본적으로 마지막 페이지까지 데이터를 추출하는 경우를 고려하여 만든 것
- 반복문
- page 값이 1부터 page + 1 의 값까지 번위에서 반복하는 루프 시작
- requests.get() 메서드로 페이지 번호를 url 에 추가하여 해당 url에서 데이터에 대한 요청 보냄 >> req 에 저장
- pd.read_html() 메서드로 응답의 html 내용을 읽고 DataFrame의 리스트로 파싱
- ignore_index=True 매개변수는 각 반복 후 DataFrame의 인덱스를 재설정하여 중복 인덱스 값을 방지
- pd.concat() 를 사용하여 df 에 새로 가져온 데이터프레임을 이어붙임
- if count > 10 : break 라는 조건은 10번의 반복(즉, 10개의 페이지) 이후에 크롤링을 중단
- 반복 루프 이후, df.dropna() 를 통해, 데이터프레임에서 결측치가 포함된 행 제거
- reset_index 를 사용하여, 인덱스를 새로운 연속적 정수 인덱스로 재설정
- 최종 데이터 프레임을 return
def getData(url, com_code, soup, page):
df = None
count = 0
for page in range(1, page + 1):
headers = { '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' }
req = requests.get(f'{url}&page={page}', headers=headers)
# 테이블이 있는 html은 매우 다행스럽게도 매우 쉽게 접근이 가능하다.
# read_html 메서드를 활용한다.
df = pd.concat([df, pd.read_html(req.text, encoding = "euc-kr")[0]], ignore_index=True)
if count > 10:
break
count += 1
data = df.dropna().reset_index(drop=True)
return data
🔎 crawler()
- url 에 회사코드를 추가하여 최종 url 을 만든다.
- UserAgent 객체를 생성하여 브라우저 정보를 지정한다.
- 생성한 최종 url로 HTTP GET 요청을 보내고 >> response에 저장
- 요청에 대해 응답 받은 HTML 내용을 BeautifulSoup으로 파싱
- 생성한 URL과 파싱한 soup 객체를 return
def crawler(url, com_code):
url = url + com_code
ua = UserAgent()
headers = { 'user-agent': ua.ie }
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.content, "html.parser")
return url, soup
🔎 getLastPage()
- 이 함수는 soup 에서 마지막 페이지 번호를 추출하는 과정이다.
- 마지막 페이지에 대한 html 코드를 확인하면 다음과 같다
- 마지막 페이지 번호를 찾기 위해
- td.pgRR 선택자를 찾고, a['href'] 속성을 가져와, = 를 기준으로 분할하고, 마지막 부분만 떼어냄 >> 이를 last_page 객체에 저장 (여기서는 681이 마지막 페이지인 것으로 보인다.)
- 추출한 last_page를 return
def getLastPage(soup):
# 여기가 핵심 포인트
last_page = int(soup.select_one('td.pgRR').a['href'].split('=')[-1])
return last_page
🔎 main()
- 지금까지 만든 함수를 종합하여 main 함수를 작성한다.
- 기준이되는 종목코드 없는 url을 지정
- 데이터를 가지고 오고 싶은 종목코드 번호를 com_code 에 지정
- 앞서 지정한 url 과 com_code를 crawler 함수에 넣어, com_url 과 soup를 return
- 종목코드에 해당하는 회사의 일별 시세가 soup에 담겨있음!
- getLastPage 함수로 soup에 담긴 데이터가 몇 페이지까지 있는지 확인
- last_page 값 return
- result 에 getData 함수를 적용 : 결과를 result에 저장하여 print!
- url 에는 com_url (crawler함수의 리턴값에 포함되어 있음)
- com_code 에는 main 에 지정된 종목코드
- soup : (crawler함수의 리턴값에 포함되어 있음)
- page 에는 last_page
def main():
url = "https://finance.naver.com/item/sise_day.nhn?code="
com_code = '005930' # 삼성전자 다른 종목을 이용할 때 활용
com_url, soup = crawler(url, com_code)
last_page = getLastPage(soup)
result = getData(com_url, com_code, soup, last_page)
print(result)
if __name__ == "__main__":
main()
728x90
'Programming Basics' 카테고리의 다른 글
[크롤링] 셀레늄(selenium) 활용 ; nate 검색어 1위부터 10까지 가져오기(동적화면에서의 크롤링) (0) | 2023.08.08 |
---|---|
[크롤링] 셀레늄(selenium) 활용 ; 구글 검색 후 이미지 다운로드 (0) | 2023.08.08 |
[웹 크롤링] 네이버 증권에서 '종목코드', '상장회사', '주가' 크롤링하기 (0) | 2023.08.04 |
[웹 크롤링] 벅스에서 Top 100 노래 제목 크롤링하기 (0) | 2023.08.04 |
[웹 크롤링] 네이버 연합뉴스의 타이틀 크롤링 (0) | 2023.08.04 |