1. 주제 선정
네이버 뉴스의 경제 메뉴에서 하부 메뉴의 기사 제목들을 스크랩하고, '환율' 관련 기사가 몇 개 인지 수집
https://news.naver.com/main/list.naver?mode=LS2D&sid2=259&sid1=101&mid=shm&date=20220930&pag
2. 수집 목표
2-1. 네이버 뉴스 경제 메뉴의 각 탭 별(ex.금융, 증권, 산업 등) 기사를 스크랩한다.
2-2. 페이지 별로 수집하는 코드를 짠다.
2-3. '환율' 키워드를 검색하는 코드를 넣는다.
2-4. 판다스 데이터프레임으로 데이터를 저장.
2-5. 저장한 데이터 시각화
3. 시작하기 전
3.1 유튜브 나도코딩 강의 무작정 따라하기
5시간 분량이라 뉴스 스크래핑을 실습하는 부분으로 건너가 따라해보았다.
def scrape_economic_news(): 해서 실행하면 아무것도 실행되지 않았다. 이유를 알 수 없었다.
각 코드가 뭘 뜻하는지도 전혀 모르겠어서, 결국 처음부터 영상을 보기로 결정했다.
3.2 나도코딩 웹툰 실습 따라하기
이걸 따라하다 보니
- res가 response를 줄인거구나
- response에 requests.get(url) 한 걸 담아두는 거구나
- 이렇게 불러온 내용을 (response.text 문서) BeautifulSoup 객체로 가져와서 soup이라는 변수에 담아둔 거구나
- lxml이나 html.parser는 파서구나
- get_text, soup.a 등을 통해 원하는 태그의 정보를 가져올 수 있구나
- attrs는 attribute구나
- attrs를 개발자모드(F12)에서 어디서 찾는구나
등을 이해하게 되었다.
import requests
from bs4 import BeautifulSoup
url = "https://comic.naver.com/webtoon/weekday"
response = requests.get(url)
# 문제가 생겼을 때 프로그램 종료
response.raise_for_status()
# 우리가 가져온 문서(response.text)를 lxml 파서를 통해 BeautifulSoup 객체로 만든것
soup = BeautifulSoup(response.text, "lxml")
# soup.title하면 <title>태그 전체 내용 가져오는데, soup.title.get_tex()하면 내용만 가져온다
print(soup.title.get_text())
# soup에서 첫번째로 발견되는 a태그 정보를 찾아줘
print(soup.a)
# attribute 속성 보기 {'href': '#menu', 'onclick': "document.getElementById('menu').tabIndex=-1;document.getElementById('menu').focus();return false;"}
print(soup.a.attrs)
# #menu가 나온다.
print(soup.a["href"])
# soup 객체 내 a 태그에 해당하는데 클래스 속성이 Nbtn_upload인 애들만 찾아줘.
print(soup.find("a", attrs = {"class" : "Nbtn_upload"}))
print(soup.find("li", attrs = {"class" : "rank01"}))
# 출력결과 : 싸움독학-147화 : 나랑 결혼 하자고?!
rank1 = soup.find("li", attrs = {"class" : "rank01"})
print(rank1.a.get_text())
3.3 네이버 API 시도해보기
그냥 API 예제를 긁어와서 검색하고자 하는 키워드만 바꿔주면 원하는 정보가 출력이 된다.
- 대신 몰랐는데 기사가 아니라 블로그 글을 수집하도록 설정 되있기 때문에 그 부분도 바꿔봐야 한다는 것
- 출력된 형태를 내가 원하는 형태로 바꾸려면 그것은 또 다시 고민이 필요하겠다고 생각하게 되었다.
4. 미니 프로젝트 실습 시작
import pandas as pd
import numpy as np
import requests
from bs4 import BeautifulSoup
# requests를 통해 url을 가져오고, BeautifulSoup을 통해 불러온 url의 text들을 headline에 저장해놓는다.
url = "https://news.naver.com/main/list.naver?mode=LS2D&mid=shm&sid1=101&sid2=259"
response = requests.get(url, headers = {"user-agent" : "Mozilla/5.0"})
response.raise_for_status()
soup = BeautifulSoup(response.text, "lxml")
headline = soup.find("ul", attrs = {"class" : "type06_headline"}).find_all("li")
# 출력되는 형식을 함수 설정해주기
def print_news(index, title, link):
print("{}. {}".format(index+1, title))
print(" (링크 : {})".format(link))
# 첫 번째 페이지의 상단 뉴스 10개 가져오기
headline1 = soup.find("ul", attrs = {"class" : "type06_headline"}).find_all("li")
for index, news in enumerate(headline) :
a_index = 0
img = news.find("img")
if img:
a_index = 1
a_tag = news.find_all("a")[a_index]
title = a_tag.get_text().strip()
link = a_tag["href"]
print_news(index, title, link)
# 리스트에 넣어주기
headline1_list = []
for t in headline1:
headline1_list.append(t.text)
# 첫 번째 페이지의 하단 뉴스 10개 가져오기
headline2 = soup.find("ul", attrs = {"class" : "type06"}).find_all("li")
for index, news in enumerate(headline) :
a_index = 0
img = news.find("img")
if img:
a_index = 1
a_tag = news.find_all("a")[a_index]
title = a_tag.get_text().strip()
link = a_tag["href"]
print_news(index, title, link)
# 리스트에 넣어주기
headline2_list = []
for t in headline2:
headline2_list.append(t.text)
# 딕셔너리 형태로 변환
dict = {"상단" : headline1_list, "하단" : headline2_list}
# 데이터프레임으로 출력 (인코딩 오류, 0부터 시작하는 인덱스 고치기)
news_df = pd.DataFrame(dict)
news_df
5. 해결해야 할 부분
5.1 headline들을 def scrape_news():로 함수 안에 넣어주기
5.2 데이터 프레임 인코딩 해결
5.3 금융 말고 다른 탭 기사도 긁어오기
5.4 여러 페이지 긁어오기
5.5 '환율' 키워드 찾기
6. 참고해서 문제 해결해보자
6.1 https://blog.naver.com/un0087/222625977401 : type06_headline과 type06로 url 리스트 만들기
6.2 https://blog.naver.com/ky_s1919/222221259483 : 뉴스 탭 별 url 수집하기
7. 느낀점
- 수업을 따라가면서 웹 스크래핑 과정을 잘 이해했다고 생각했는데, 스스로 해보니 url을 request로 불러오고, BeautifulSoup을 통해 text로 저장해두는 일련의 과정조차 이해하지 못했다는 것을 깨달아서, 유튜브 강의를 반복해서 돌려보았다.
- 아직도 파서를 json, html, lxml 로 불러오는 방식의 차이를 구별하지 못하겠고, url이 있을 때 바꿀 수 있는 파라미터를 {}로 바꿔서 가져온다거나, 그냥 url을 불러온 다음 태그를 통해 불러오거나 하는 등의 부분이 어렵다.
- 어떤 부분에 막혔을 때, 어떤 키워드로 검색해야 할 지 감조차 잡히지 않을 때가 많아서 시간 소모가 많이 되었다.
- 반복문이나 함수 정의를 원활하게 사용하여야 부문별 기사, 페이지별 기사를 수집할 수 있을 것 같다.
- 6개로 나눈 개요 중 혼자 구현할 수 있었던 부분이 너무 적어서, 미니 프로젝트가 끝나고 나서도 공부하면서 해결해서 끝마치고 싶은 목표가 생겼다.
- 프로젝트가 처음이라 코드 리뷰 부분을 잘 못 이끈 것 같은데, 다른 코드를 보면서 배우고, 서로의 코드를 고민해볼 수 있게 그 부분에 대해서 고민을 조금 더 해봐야겠다.
- 시간이 날 때마다 다른 조 데이터 수집도 도전해보고 싶다.
댓글