[웹크롤링] 웹 데이터 수집해서 저장하기 (Pandas, BeautifulSoup)

영릿·2023년 2월 2일
0

Pandas 공부방

목록 보기
1/1
post-thumbnail

웹크롤링이란 용어가 널리 사용되서 웹크롤링이라고 썼지만 스크래핑에 더 가까운 실습입니다. 본 실습 과정은 멋쟁이사자처럼 AI스쿨에 저작권이 있습니다.


네이버 금융 뉴스 기사 수집하기

수집할 URL가져오기

  • 웹페이지 전체가 아니라 일부 데이터만을 가져올 것이기 때문에, 해당 부분의 링크를 찾아내는 것이 필요하다
  • 구글 크롬 웹브라우저의 검사(inspector) - 네트워크 - Doc를 참고하면 Requests URL 주소를 알 수 있다.
  • 가져온 URL주소에서 변하는 부분과 변하지 않는 부분을 구분하여 f스트링을 통해 변수를 넣어주면 준비 완료
item_code = "035420"
item_name = "네이버"
page_no = 1

url=f"https://finance.naver.com/item/news_news.nhn?code={item_code}&page={page_no}&sm=title_entity_id.basic&clusterId="

URL의 데이터를 Pandas DataFrame에 담기

  • 연습하기 쉽도록 Table형식으로 되어있는 URL을 선정하였음
  • read_html로 수집하고, df라는 변수에 담기
  • 반복문으로 데이터 모두 가져오기 (for문)
table = pd.read_html(url)

#table변수의 0번쨰 인덱스 값을 df에 넣었음 
df = table[0]
cols =  df.columns

# 반복문으로 데이터 가져오기
temp_list = []
for news in table[:-1]: 
    news.columns = cols
    temp_list.append(news)

데이터 합치고, 가공하기

  • Concat 활용하기
  • 결측치 제거
  • 인덱스 리셋
df_news = pd.concat(temp_list)
df_news = df_news.dropna()
df_news = df_news.reset_index(drop=True)
df_news = df_news.drop_duplicates()

특정 조건을 가지고 있는 데이터 제거

  • .str.contains / 반대로 적용하려면 앞에 "~"붙이기
df_news = df_news[~df_news["정보제공"].str.contains("연관기사")].copy()

전 과정을 하나의 함수로 만들어보기

  • 독스트링을 작성하는 것이 중요하다
  • 함수가 어떻게 동작하는지 전체 과정을 논리적으로 정리해보면 나중에 코딩테스트를 풀때도 매우 도움이 된다.
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) 데이터프레임 반환
    """
    url = f"https://finance.naver.com/item/news_news.nhn?code={item_code}&page={page_no}&sm=title_entity_id.basic&clusterId="
    table = pd.read_html(url)
    df = table[0]
    cols =  df.columns
    
    temp_list = []
    for news in table[:-1]:
        news.columns = cols
        temp_list.append(news)

    df_news = pd.concat(temp_list)
    df_news = df_news.dropna()
    df_news = df_news.drop_duplicates()
    df_news = df_news.reset_index(drop=True)
    df_news = df_news[~df_news["정보제공"].str.contains("연관기사")].copy() 
    return df_news

반복문을 통해 여러 페이지 가져오기

  • for문 : 페이지 수가 정해져 있는 경우 in range(1, 가져올 페이지수)로 활용한다
  • while문 : 페이지의 끝 번호를 모를 경우 조건을 걸어 break할 수 있도록 작성한다.
  • 예를들어 수집되는 페이지의 정보가 이전과 같다면 break
  • 같지 않다면 계속 추가, 페이지 수 += 1, time.sleep(0.01)

FinanceDataReader

tqdm

파이썬 진행 상태를 보다 명확하게 나타내주는 라이브러리이다.
아래와 같이 trange와 함께 사용한다.

import time
from tqdm import trange

# item_code = "035420"
item_name = "카카오페이"
item_code = df_krx.loc[df_krx["Name"] == item_name, "Symbol"].values[0]

news_list = []
for page_no in trange(1,11):
    temp = get_one_page_news(item_code, page_no)
    news_list.append(temp)
    time.sleep(0.01)

csv 파일로 저장하기

file_name = f"news_{item_code}_{item_name}.csv"

# to_csv
df_news.to_csv(file_name, index= False)

# read_csv
pd.read_csv(file_name)

# 파일명에 변수 넣기
date = df_day.iloc[0]["날짜"]
file_name = f"{item_name}_{item_code}_{date}.csv"
df_day.to_csv(file_name, index = False)

Requests란?

It is an elegant and simple HTTP library for Python, built for human beings.

웹과의 소통을 편하게 해주는 라이브러리이다. HTTP 요청을 간단한 메소드를 통해 실행할 수 있도록 짜여져 있다.

BeautifulSoup

HTML페이지를 파싱하는 용도의 라이브러리이다. 파싱(parsing)이란 웹페이지를 해석하고, 정보를 찾는 기능을 말한다.

쉽게 이해하면 가져온 HTML페이지를 보기 쉽게 정리해주는 역할을 한다.

불러오기
from bs4 import BeautifulSoup as bs

활용법

  • bs(가져올.text) -> 예시 bs(response.text)

  • bs(가져올.text).title : 네이버 금융

  • bs(가져올.text).title.string : 네이버 금융

  • bs(가져올.text).find_all(”a”) : 모든 a 태그를 찾는다

  • bs(가져올.text).select(”table > tr > td”):

  • select는 직접 copyselector로 찾아 가져올 수 있기 때문에 유용하다

profile
데이터분석가를 꿈꾸고 있습니다

0개의 댓글