뒤죽박죽 데이터분석 일기장
[Pandas] 판다스 기초 - 네이버 증권 기사 크롤링 본문
안녕하세요! 이번 포스트에서는 Pandas에서 read_html 이라는 기능을 통해서 테이블 형태의 표를 수집하는 방법을 알아보겠습니다!
read_html의 기능을 제대로 이해하기 위해서 네이버 증권에서 데이터 스크래핑으로 진행해 보겠습니다.

우리의 목표는 이 페이지에 나타나 있는 뉴스들을 스크랩핑해서 저장하는 것입니다.
이 페이지의 URL은 https://finance.naver.com/item/news.naver?code=005930입니다.
네이버의 종목 코드는 005930 입니다. 즉, 위의 URL을 살펴보면 code=005930 이라고 적힌 것을 확인할 수 있습니다.
이렇게 특정 코드를 URL에 붙여서 넘기는 문구를 Query String이라고 합니다.

따라서 URL 뒤에 물음표 뒤에서부터 검색하려고 페이지의 파라미터 정보가 적혀있습니다.
크롤링 하는 브라우저는 파라미터가 1개. 종목 코드만 있는 브라우저 입니다. 응용하자면 만약 CJ 관련 종목 페이지를 보고 싶으면 CJ 종목 코드를 입력하면 CJ 종목 페이지로 넘어갑니다.
pd.read_html
우리는 판다스의 read_html 함수를 사용해 크롤링을 진행할 것입니다.
pd.read_html의 기능을 설명하자면
import pandas as pd
url = "https://finance.naver.com/item/news_news.naver?code=005930&page=3&sm=title_entity_id.basic&clusterId="
temp_table = pd.read_html(url, encoding='cp949') #인코딩 깨짐 방지
temp_table
결과:

이렇게 리스트 형태로 출력하는 것을 확인할 수 있습니다.
반복문으로 데이터를 모두 가져와보겠습니다.
# table[:-1] => 맨마지막 데이터프레임은 페이징 테이블이기 때문에 제외하고 가져옵니다.
# [0, 1, 2] 로 되어있는 컬럼명을 ['제목', '정보제공', '날짜'] 로 변경해 주기위해
# 데이터프레임을 하나씩 불러와서 컬럼명을 변경해 줍니다.
temp_list = []
for news in table[:-1]: #페이지 숫자
news.columns = cols
print(news.columns)
display(news)
temp_list.append(news)
그러고 temp_list에 모은 데이터를 pd.concat 함수를 이용해 데이터프레임으로 합칠 수 있습니다.
df_one_page = pd.concat(temp_list)
df_one_page
결측치도 제거해야됩니다.
# dropna
df = df_one_page.dropna()
df.shape
연관기사도 제거해 주겠습니다. 이때는 pd.Series를 이용해서 불릴 형태로 출력해보겠습니다.
df_one_page = df_one_page[~df_one_page['제목'].str.contains('연관기사')]
df_one_page.head()
위의 모든 과정을 하나의 함수로 표현해보자면
# get_url_item_code, page_no 를 넘기면 url을 반환하는 함수
def get_url(item_code, page_no):
#docstring 만들기
'''item_code, page_no 를 넘기면 url 을 반환하는 함수
'''
url = f"https://finance.naver.com/item/news_news.naver?code={item_code}&page={page_no}"
return url
위의 함수에 종목 코드 그리고 출력하고자 하는 페이지의 번호를 입력하면 그 페이지의 뉴스를 출력해줍니다.
이번에는 반복문을 사용해 몇 페이지까지 모든 뉴스 정보를 크롤링 해보겠습니다.
# get_one_page_news 함수 만들기
def get_one_page_news(item_code, page_no):
"""
get_url 에 item_code, page_no 를 넘겨 url 을 받아오고
뉴스 한 페이지를 수집하는 함수
1) URL 을 받아옴
2) read_html 로 테이블 정보를 받아옴
3) 데이터프레임 컬럼명을 ["제목", "정보제공", "날짜"]로 변경
4) tmp_list 에 데이터프레임을 추가
5) concat 으로 리스트 병합하여 하나의 데이터프레임으로 만들기
6) 결측치 제거
7) 연관기사 제거
8) 중복데이터 제거
9) 데이터프레임 반환
"""
# 1) URL 받아오기
temp_url = get_url(item_code, page_no)
# 2) read_html 로 테이블 정보를 받아옴
table = pd.read_html(temp_url)
# tmp_list = [] 빈 리스트
tmp_list =[]
for tmp in table[:-1]:
# 3) 데이터프레임 컬럼명을 ["제목", "정보제공", "날짜"]로 변경
tmp.columns = table[0].columns
# tmp_list 에 데이터프레임을 추가
tmp_list.append(tmp)
# 5) concat 으로 리스트 병합하여 하나의 데이터프레임으로 만들기
df_one = pd.concat(tmp_list)
# 6) 결측치 제거
df_one = df_one.dropna()
# 7) 연관기사 제거
df_one = df_one[~df_one["제목"].str.contains("연관기사")]
# 8) 중복데이터 제거
df_one = df_one.drop_duplicates()
return df_one
이렇게 쉽게 함수를 생성해서 기사를 크롤링 할 수 있었습니다.
'Pandas' 카테고리의 다른 글
| [Pandas] 판다스 기초 - 네이버 증권 일일 시세 크롤링 (0) | 2023.01.14 |
|---|---|
| [Pandas] 판다스 기초 1 (0) | 2023.01.12 |