Pandas - pd.read_html을 통해서 테이블 형태의 표를 수집
1) 검색 값 설정
● (pd.read_html( )의 기능):
url, html 소스코드 넣어주면 페이지의 테이블 태그를 읽고 가져와서 리스트 형태로 반환
반환 된 리스트 인덱싱하면 데이터프레임형태
url = 'https://finance.naver.com/item/news.naver?code=005930'
temp_table = pd.read_html(url, encoding='cp949')
len(temp_table)
-------------------------------------------------------------
9
#인덱싱하여 데이터프레임 형태로 보기
temp_table[7]
# 웹스크래핑은 리버스엔지니어링과 유사합니다.
2) 뉴스페이지 가져오기 :
for 문 사용하여 url의 item_code & page_no 변경하여
원하는 종목의, 원하는 페이지 수 만큼의 뉴스 가져오기
item_code = '035720'
item_name = '카카오'
page_no = 1
# url
for page_no in range(1, 6):
url = f'https://finance.naver.com/item/news_news.nhn?code={item_code}&page={page_no}'
print(url)
------------------------------------------------------------------------------------------
https://finance.naver.com/item/news_news.nhn?code=035720&page=1
https://finance.naver.com/item/news_news.nhn?code=035720&page=2
https://finance.naver.com/item/news_news.nhn?code=035720&page=3
https://finance.naver.com/item/news_news.nhn?code=035720&page=4
https://finance.naver.com/item/news_news.nhn?code=035720&page=5
3) read_html로 수집하기
- 네이버 금융의 주가 기사를 read_html로 수집해서 table 이라는 변수에 담습니다.
table = pd.read_html(url)
table
4) 데이터프레임으로 만들기
- 위에서 수집한 결과 중 table 변수 안에 있는 0번째 인덱스 값을 가져와서 df 라는 변수에 담아주세요.
df = table[0]
df
5) 반복문으로 데이터 가져오기 +의문점 포함
- for 문을 사용해 table 이라는 변수 안에 있는 값을 모두 가져오기
- temp_list 에 수집한 값을 담기
가져온 read_html(url) 데이터 ( 테이블 태그들의 리스트 형태) 의
0번 인덱스 열들을 보면 이미 [0, 1, 2] 가 아닌 ['제목', '정보제공', '날짜']로 되어있는데 왜 바꿔주는거지..?
cols = table[0].columns
cols
------------------------
Index(['제목', '정보제공', '날짜'], dtype='object')
temp_list = []
for news in table[:-1]:
news.columns = cols
temp_list.append(news)
display(news)
# for news in table:
6) 수집한 데이터 하나의 데이터프레임으로 합치기
●pd.concat() : 기존에 존재하는 데이터를 merge 하는 기능
●concat :
-axis=0 행을 기준으로 위아래로 같은 컬럼끼리 값을 이어 붙여 새로운 행을 만듦
-axis=1 컬럼을 기준으로 인덱스가 같은 값을 옆으로 붙여 새로운 컬럼을 만듦
df_one_page = pd.concat(temp_list)
df_one_page
7) 수집한 데이터의 결측치 제거
●.dropna( ) : 행이나 열 중에서 결측치가 들어있는 행,열 모두 제거
- axis 행,열 중에 무엇을 기준으로 삭제할 것인지
- axis : {0 or 'index', 1 or 'columns'}, default 0
- 기본적으로 dropna() 는, 모든 컬럼 데이터 중 하나라도 빠진 데이터가 있다면, 그 행을 삭제해버립니다.
df_one_page.shape
df = df_one_page.dropna()
df.shape
-------------------------
(13, 3)
8) 네이버 수집한 기사에서 '제목'에 '연관기사'가 들어가는 데이터 제거
●.str.contains( ) : 문자열 메서 드이며, 지정한 문자열 포함되어있는지 확인 가능
- 를 사용하며 조건의 반대에는 앞에 ~ 표시로 표현할 수 있습니다.
pd.Series([True, False])
------------------------
0 True
1 False
dtype: bool
~pd.Series([True, False])
-------------------------
0 False
1 True
dtype: bool
~(df['제목'].str.contains('연관기사'))
9) 위 과정 함수로 제작
- 빈칸을 완성해 수집한 table 을 넘겨주면 데이터프레임을 반환하는 함수를 완성해 주세요.
def get_url(item_code, page_no):
"""
item_code, page_no 를 넘기면 url 을 반환하는 함수
"""
url = f'https://finance.naver.com/item/news_news.nhn?code={item_code}&page={page_no}'
return url
get_url('035720',1)
------------------------------------------------------------------------------------------
'https://finance.naver.com/item/news_news.nhn?code=035720&page=1'
10) 뉴스 한 페이지를 수집하는 함수
1) URL 을 받아옴
2) read_html 로 테이블 정보를 받아옴
3) 데이터프레임 컬럼명을 ["제목", "정보제공", "날짜"]로 변경
4) temp_list 에 데이터프레임을 추가
5) concat 으로 리스트 병합하여 하나의 데이터프레임으로 만들기
6) 결측치 제거
7) 연관기사 제거
8) 중복데이터 제거
9) 데이터프레임 반환
def get_one_page_news(item_code, page_no):
"""
get_url 에 item_code, page_no 를 넘겨 url 을 받아오고
뉴스 한 페이지를 수집하는 함수
1) URL 을 받아옴
2) read_html 로 테이블 정보를 받아옴
3) 데이터프레임 컬럼명을 ["제목", "정보제공", "날짜"]로 변경
4) temp_list 에 데이터프레임을 추가
5) concat 으로 리스트 병합하여 하나의 데이터프레임으로 만들기
6) 결측치 제거
7) 연관기사 제거
8) 중복데이터 제거
9) 데이터프레임 반환
"""
news_url = get_url(item_code,page_no) #1 url 받아오는 함수
table = pd.read_html(news_url, encoding = 'cp949') #2 read_html 로 테이블 정보를 받아옴
cols = table[0].columns
temp_list = []
for news in table[:-1]:
#3 데이터프레임 컬럼명을 ["제목", "정보제공", "날짜"]로 변경
news.columns = cols
#4 temp_list 에 데이터프레임을 추가
temp_list.append(news)
#5 concat 으로 리스트 병합하여 하나의 데이터프레임으로 만들기
df_one_page = pd.concat(temp_list)
#6 결측치 제거
df_one_page = df_one_page.dropna()
#7 연관기사 제거
df_one_page = df_one_page[~df_one_page['제목'].str.contains('연관기사')]
#8 중복데이터 제거
df_one_page = df_one_page.drop_duplicates()
return df_one_page
10-1) 뉴스 한 페이지를 수집하는 함수( 잘 나오는지 확인 )
page_no = 7
temp = get_one_page_news(item_code, page_no)
temp
11) 반복문을 사용해 10페이지까지 수집
- 위에서 만든 함수를 활용합니다.
- time.sleep() 을 통해 데이터를 쉬었다 가져오기
●trange : for문의 range 함수 자리에 쓰이며, for문의 반복과정을 %및 그래프로 표시
import time
from tqdm import trange
page_no = 10
item_code = '005930' #삼성전자
news_list = []
for i in trange(1, page_no + 1):
news_list.append(get_one_page_news(item_code, page_no))
#수집 대상 서버의 부담을 줄이기 위해 쉬었다가 가져옵니다.
time.sleep(1)
display(news_list)
-----------------------------------------------------------
12) news_list에 담겨있는 뉴스페이지들
-> 판다스 활용해서 하나의 데이터프레임으로
df_news_list = pd.concat(news_list)
df_news_list = df_news_list.reset_index(drop + True)
df_news_list.tail()
13) 파일로 저장하기
file_name = f"news_{item_code}_{item_name}.csv"
file_name
df.to_csv(f"news_{item_code}_{item_name}.csv", index = False)
pd.read_csv(f"news_{item_code}_{item_name}.csv")
'Python > ▶ Python & Pandas' 카테고리의 다른 글
5주차 plotly (1) | 2023.02.05 |
---|---|
5주차 TIL ( Pandas : 시각화 ) (0) | 2023.01.31 |
4주차 WIL (1) | 2023.01.19 |
TIL ①-2일차 (0) | 2023.01.10 |
TIL ①일차 (0) | 2023.01.09 |