데이터분석종합반 2일차

전윤환·2022년 5월 31일
0

데이터분석종합반

목록 보기
3/7

데이터분석종합반 2일차
스파르타코딩클럽 데이터분석종합반
학습일자: 2022/05/31
강의: 데이터분석종합반
진도: 1-13 ~ 1-14

============================
오늘 첫 강의는 시간이 무려 40분!
뭘 가르쳐주려나 두근두근

============================
실습 과정

  1. 각각의 뉴스가 가진 url을 리스트 형태로 저장
  2. 각각의 뉴스가 가진 url에 접근, 제목과 본문을 newpaper3k로 크롤링
  3. 크롤링할 때마다 데이터프레임에 이어붙임(concat)
  4. 크롤링이 끝난 뒤 정보가 저장된 데이터프레임을 저장

필요한 모듈
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를 써줘야 한다는 사실

============================

profile
코딩 연습장. 발전하고 싶습니다. 모든 방향에서의 비판 부탁드립니다.

0개의 댓글