데이터분석종합반 2일차
스파르타코딩클럽 데이터분석종합반
학습일자: 2022/05/31
강의: 데이터분석종합반
진도: 1-13 ~ 1-14
============================
오늘 첫 강의는 시간이 무려 40분!
뭘 가르쳐주려나 두근두근
============================
실습 과정
- 각각의 뉴스가 가진 url을 리스트 형태로 저장
- 각각의 뉴스가 가진 url에 접근, 제목과 본문을 newpaper3k로 크롤링
- 크롤링할 때마다 데이터프레임에 이어붙임(concat)
- 크롤링이 끝난 뒤 정보가 저장된 데이터프레임을 저장
필요한 모듈
requests, pandas, newpaper(Article), bs4(BeautifulSoup)
필요한 모듈들을 임포트
import requests
import pandas as pd
from newspaper import Article
from bs4 import BeautifulSoup
# 2020년 5월 6일자(date) 경제분야(101) 1페이지(1)
page_num = 1
code = 101
date = 20200506
# 문자열은 더하면 이어붙이기가 된다
# 문자열과 숫자는 더할 수 없다 -> 숫자를 문자열로 바꿔주는 작업을 해야한다
url = 'https://news.naver.com/main/list.nhn?mode=LSD&mid=sec&sid1='+str(code)+'&date='+str(date)+'&page='+str(page_num)
print(url)
# >>https://news.naver.com/main/list.nhn?mode=LSD&mid=sec&sid1=101&date=20200506&page=1
============================
# requests로 데이터 불러오기.
# 헤더 설정
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36'}
news = requests.get(url, headers=headers)
news.content
============================
# 함수 코딩하기
# 각 기사의 URL 주소를 가져와서 리스트에다가 담아주는 함수
# 크롤링할 페이지 수, 카테고리, 날짜
def make_urllist(page_num, code, date):
# 각각 기사들이 가진 url을 저장하기 위한 빈 리스트를 하나 만들어놓는다.
urllist= []
# 1 ~ page_num까지 정해진 페이지만큼 반복.
for i in range(1, page_num + 1):
# 함수의 입력으로 된 변수들로 주소를 조합
url = 'https://news.naver.com/main/list.nhn?mode=LSD&mid=sec&sid1='+str(code)+'&date='+str(date)+'&page='+str(i)
# requets 패키지의 모듈(함수)을 호출
# import 패키지이름 으로 '임포트'했다면 '패키지이름.모듈이름' 으로 모듈을 호출합니다.
news = requests.get(url, headers=headers)
news.content
# BeautifulSoup 모듈을 사용하여 HTML 페이지를 분석
soup = BeautifulSoup(news.content, 'html.parser')
# 해당 페이지에 있는 각각의 뉴스가 news_list 라는 리스트로 저장됩니다!
news_list = soup.select('.type06_headline li dl')
news_list.extend(soup.select('.type06 li dl'))
# 뉴스 리스트에 있는 각 뉴스로부터 a 태그인 <a href ='주소'> 에서 '주소'만을 가져온다.
for line in news_list:
urllist.append(line.a.get('href'))
return urllist
============================
# 딕셔너리로 사회,경제,it등 뉴스카테고리 지정
# 파이썬의 dictionarys는 선언 할 때는 'key' : 'value'의 형태로 선언을 합니다.
idx2word = {'101' : '경제', '102' : '사회', '103' : '생활/문화', '105' : 'IT/과학'}
# url과 카테고리를 알려주면 url로부터 본문을 추출하여 데이터프레임을 생성하는 함수.
def make_data(urllist, code):
# 본문을 저장하기 위한 빈 리스트를 만들어놓는다.
text_list = []
for url in urllist:
article = Article(url, language='ko')
article.download()
article.parse()
text_list.append(article.text)
df = pd.DataFrame({'news': text_list})
df['code'] = idx2word[str(code)]
return df
============================
# 함수로 크롤링할 뉴스카테고리 지정
code_list = [102, 103, 105]
# 원하는 날짜, 원하는 페이지 수, 수집을 원하는 카테고리를 입력.
def make_total_data(page_num, code_list, date):
# 아무것도 들어있지 않은 데이터 프레임을 만든다
df = None
# 각 카테고리에 대해서 아래의 코드를 수행.
for code in code_list:
# make_urllist 함수 : 페이지 수, 카테고리, 날짜를 입력하면 url을 추출하는 함수.
url_list = make_urllist(page_num, code, date)
# make_data 함수: url과 카테고리를 알려주면 데이터프레임을 만들어주는 함수
df_temp = make_data(url_list, code)
print(str(code)+'번 코드에 대한 데이터를 만들었습니다.')
if df is not None: # df가 채워져있나요?
# for문 내에서 데이터프레임이 새로 만들어질 때마다
# 이전 데이터프레임과 지속적으로 결합
df = pd.concat([df, df_temp])
else:
df = df_temp
return df
============================
# 함수를 통해 뉴스 크롤링
# 10페이지, code_list의 모든 분야, 2020년 5월6일자
df = make_total_data(10, code_list, 20200506)
# 데이터를 엑셀파일로 저장(인덱스는 제외)
df.to_csv('news_data.csv', index=False)
# 저장한 엑셀파일을 불러오기
df = pd.read_table('news_data.csv', sep=',')
============================
1-14. 1주차 끝 & 숙제 설명
지니 뮤직의 1~50위 크롤링 코드 짜기
지니뮤직 차트200 웹사이트 주소
https://www.genie.co.kr/chart/top200
크롤링 단계 구상
1. requests로 데이터 긁기
2. beautifulsoup으로 파싱
3. 순위, 제목, 가수가 적혀있는 선택자 파악
4. 반복문으로 순위, 제목, 가수 뽑아오기
필요한 모듈: requests, beautifulsoup
지니뮤직 1~50위 크롤링 코드
import requests
from bs4 import BeautifulSoup
url = f'https://www.genie.co.kr/chart/top200?ditc=D&ymd=20211103&hh=13&rtm=N&pg=1'
headers = headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36'}
data = requests.get(url, headers=headers)
# print(data) # 200
soup = BeautifulSoup(data.text, 'html.parser')
# print(soup) # html 불러옴
way = f'#body-content > div.newest-list > div > table > tbody > tr'
# keypoint!
# way에서 tbody가 아닌 tr을 찍은 이유는?
# soup.select()를 쓰면 그에 해당하는 모든 html을 다 불러오기 때문에 tr까지만 해도 tr에 해당하는 모든 텍스트를 불러오기 때문!!!
result = soup.select(way)
# print(result) # 아무튼 많은 텍스트가 들어옴
for i in result:
rank = i.select_one('td.number').text[0:2].strip()
artist = i.select_one('td.info > a.artist.ellipsis').text
title = i.select_one('td.info > a.title.ellipsis').text.strip()
print(f'{rank} | {artist} | {title}')
============================
requests, beautifulsoup에 대한 내용 리프레쉬,
newspaper3k라는 모듈(원리는 모르겠음)
strip()함수 - 인자의 좌우 공백 제거(lstrip, rstrip도 있음)
크롤링할 때 원하는 데이터를 추출하려면 뒤에 .text를 써줘야 한다는 사실
============================