* 해당 자료는 스파르타코딩 데이터분석 종합반 수업 강의를 정리한 겁니다. 스파르타에서 제공한 데이터베이스를 사용했습니다.
맛보기
correlation 상관관계
- 인과관계와 상관관계는 다름
- 두 변수 관계가 '~할 확률(가능성)이 높다' 정도로 해석 가능
구글 Colab
- 구글에서 제공하는 개발 환경
- 인터넷과 구글 계정만 있으면 별도의 셋팅 없이도 언제든 파이썬을 사용할 수 있음
- 마지막 결과값만 출력하는 특성이 있다 -> 여러 개를 출력할 때는 print() 사용
- 출력 단축키는 shift + enter
- 주석을 작성할 때는 앞에 #를 붙임
파이썬 기초
1-1. 변수
- '=' 기호는 변수를 만드는 행위로, '할당한다'라고 표현
1-2. 자료형
1) 정수형
2) 실수형
3) 문자형
4) 리스트형
- 리스트의 순서는 0부터 시작한다. [0]은 첫 번째 값을 출력
- list에 뭔가를 추가할 때 append를 쓴다. ex) list1 = apppend(6)
- extend는 리스트와 리스트를 합칠 때 씀 ex) list1 = extend(list2)
조건문/반복문
1) for문
- range(시작 숫자, 끝 숫자) : 끝 숫자는 포함하지 않고 숫자 리스트를 자동으로 만들어주는 함수
- 들여쓰기 즉 indent를 한 것만 반복된다
- 들여쓰기 단축키는 tab 또는 spacebar 4번
- for문 끝에 : (콜론)을 붙여야 함
2) 비교연산자

3) if문, else문
if 1 == 1:
# 조건문이 맞는 말일 때 실행되는 부분
print('참이네요!')
else:
# 조건문이 틀린 말일 때 실행되는 부분
print('거짓이네요!')
-> 출력값은 '참이네요!'
- for문처럼 if문의 조건에서 실행되는 코드는 들여쓰기(indentation) 후 작성해야 함
- else 뒤에는 어떠한 조건문도 붙이지 않는다
4) elif
- 조건문이 한 개가 아닐 때 사용
- if와 else 사이에 들어감
- elif 뒤에는 조건문이 들어갈 수 있음. else 뒤에는 조건문 x. 바로 : 붙여야 함
- 조건문 뒤에는 반드시 : (콜론)이 들어가야 함
score = 85
if score > 90:
print('학점이 A입니다')
elif score > 80:
print('학점이 B입니다')
elif score > 70:
print('학점이 C입니다')
else:
print('학점이 F입니다')
-> 이 경우 출력값은 '학점이 B입니다'
함수
def 함수이름(함수의 인자1, 함수의 인자2, ....):
수행할 코드
return 최종 결과
# 부피를 구하는 함수를 만든 것 뿐, 함수를 실행한 게 아님. 계산을 한 게 아니라 정의를 한 것!
def volume(width, height, length): # width, height, length 값이 있어야만 함수가 실행될 수 있다는 의미
return width * height * length # return은 결과값을 나중에 또 사용할 수 있도록 하는 조치
print(volume(5, 8, 2))
def surface_area(width, height, length):
return 2 * (width * height + width * length + height * length )
print(surface_area(2, 4, 6)
판다스와 데이터프레임
패키지
- 누군가가 이미 만들어놓은 함수, 클래스 덩어리
- import 라는 명령어를 사용해서, 그저 가져오기만 하면 바로 사용 가능
- 판다스(Pandas)는 파이썬 데이터 분석을 위한 필수 패키지 중 하나
- 데이터프레임 : Pandas가 제공하는 표 (테이블) 형태의 구조. 행과 열로 구성된 2차원 테이블. 데이터를 읽어서 저장하고 연산하는 데 많이 사용
import pandas as '사용자가 정한 이름(pd)'
# df란 이름의 데이터프레임을 생성합니다.
items = {'code' : [101, 102, 103, 104, 105, 106, 107, 108],
'과목': ['수학', '영어', '국어', '체육', '미술', '사회', '도덕', '과학'],
'수강생':[15, 15, 10, 50, 20, 50, 70, 10],
'선생님': ['김민수','김현정','강수정', '이나리', '도민성', '강수진', '김진성', '오상배']}
df = pd.DataFrame(items)
df
- df.head(숫자) : 상위 (숫자)개의 행만 출력
- df.tail(숫자) : 하위 (숫자)개의 행만 출력
- df.sample(숫자) : 랜덤으로 (숫자)개의 행 출력
concat 함수
- concatenate : 합치다
- 데이터 프레임 여러 개를 합칠 때 사용
total_df = pd.concat([df, df2])
total_df
저장하기
total_df.to_csv('data.csv')
불러오기
new_df = pd.read_table('data.csv', sep=',')
new_df
- 맨 앞 열 unnamed 없애려면 저장을 할 때 'index = False'를 뒤에 붙이면 됨
total_df.to_csv('data.csv', index=False)
웹 이해하기
크롤링(crawling)
- 웹 페이지로부터 데이터를 추출하는 것
- 크롤링하는 소프트웨어는 '크롤러(crawler)'
HTML
- 웹 페이지는 HTML이라는 웹 문서로 구성돼 있다.
- HTML이란 텍스트 덩어리. 텍스트 덩어리로 이뤄진 웹 페이지를 예쁘게 만드는 건 CSS
- HTML은 태그(<></>)로 작성한다. 태그로 이름을 붙여야 문서를 가져올 때 'head에 있는 거 가져와'라고 할 수 있음
<div class="direct_area">
<a href="http://news.naver.com/" class="link_news" data-clk="newshome">네이버뉴스</a>
<a href="http://entertain.naver.com/home" class="link_direct" data-clk="entertainment">연예</a>
<a href="http://sports.news.naver.com/" class="link_direct" data-clk="sports">스포츠</a>
</div>
- div 태그. 안에 있는 세 개의 꺾쇄는 'div 태그 안에 있다'라고 표현함
선택자(Selector)
- 웹 페이지 안 특정 구성요소의 주소
- 선택자란 HTML 문서 내의 어떤 특정 태그들에 그룹이나 ID를 주는 기능
- 선택자는 주로 'id'와 'class'를 사용
- class는 속성이나 기능을 공유하는 유사한 성질의 객체들을 하나로 묶은 것
- class 내부에는 클래스 멤버와 기능의 구현 등 세부사항을 기술함
- 인스턴스(instance)는 클래스에 의해 만들어진 객체. ex) 클래스가 붕어빵 틀이라면 인스턴스는 붕어빵
웹 스크래핑
패키지
- 이미 만들어져 있는 함수들의 묶음
- 파이썬에서는 '!pip install 패키지이름' 이라는 명령어를 통해 패키지 설치가 가능
- 설치 후에는 'from 패키지 이름 import 모듈'을 통해 패키지를 사용할 수 있음
- 이때 모듈이란 패키지 안에 저장된 함수 등을 말함
1) BeautifulSoup
- 파이썬으로 크롤링할 때 주로 사용하는 패키지는 BeautifulSoup. 이걸로 HTML이나 XML문서로부터 정보 추출이 가능함
- 인스턴스의 이름이 soup이므로 'soup.select(찾는 정보)'를 통해서 정보를 가져옴
- soup.select('태그명') : 태그를 입력으로 사용할 경우
- soup.select('.클래스명') : 클래스를 입력으로 사용할 경우
- soup.select('#아이디') : ID를 입력으로 사용할 경우
- soup.select('상위태그명 하위태그명') : 자손 관계 (어떤 태그 내부에 있는 모든 태그를 자손이라고 함)
- soup.select('상위태그명 > 하위태그명') : 자식 관계 (어떤 태그 내부에 있는 태그 중 바로 한 단계 아래에 있는 태그를 자식이라고 함)
- soup.태그명.get('속성명') : 해당 속성의 값을 가져옴. 속성이란 aaa = 'bbb' 형식 -> get('aaa') = bbb를 가져온다
2) Newspaper3k
- 뉴스 데이터를 크롤링하기 위한 패키지
- 인터넷 뉴스 기사의 url을 전달해주면 뉴스 기사의 제목과 텍스트를 추출함
# newspaper라는 패키지로부터 Article이라는 모듈을 임포트
from newspaper import Article
# 파싱할 뉴스 기사 주소
url = https://n.news.naver.com/mnews/article/030/0002881076?sid=101
# 언어가 한국어이므로 language='ko'로 설정
article = Article(url, language='ko')
# 뉴스 제목과 본문을 찾아내는 분석!
article.download()
article.parse()
# 뉴스 제목 추출
print(article.title)
# 뉴스 본문 추출
print(article.text)
뉴스 크롤링
url
- 웹페이지에 접근하는 주소
- 네이버 뉴스의 경우 url 자체에 정보값이 담겨 있음 -> 특정 정보를 크롤링하려면 url 먼저 분석해야 한다
https://news.naver.com/main/list.nhn?mode=LSD&mid=sec&sid1=105&date=20200430&page=2
- &sid1=숫자 : 숫자는 뉴스가 속한 카테고리 번호. 105는 IT/과학
- &date=날짜 : 게시 날짜
- &page=번호 : 몇 페이지인지

- 작은 사각형이 큰 사각형의 자손들. 즉, 내부 태그들
- 이 구조를 파악하면 BeautifulSoup의 select()를 사용해 url을 받아올 수 있음
- 개발자 도구를 여는 단축키 : F12(window), Command + Option + I (Mac)
네이버 뉴스 크롤링 순서
* 기초 작업 : 4개의 패키지를 임폴트 해준다
import requests
import pandas as pd
from newspaper import Article
from bs4 import BeautifulSoup
- 네이버 뉴스 페이지에서, 각각의 뉴스가 가진 URL을 리스트 형태로 만들어서 저장해놓는다.
- 각각의 뉴스가 가진 URL 에 접근하면 제목과 본문 내용이 표시가 될텐데, 그 제목과 본문 내용을 newspaper3k 패키지를 이용해서 크롤링을 진행한다.
- 크롤링을 할 때마다 크롤링 되어온 내용을 데이터프레임에 계속 이어붙인다.
- 크롤링이 끝났다면, 정보가 저장되어있는 데이터프레임을 csv 파일로 저장한다.
변수 이용해 url 변환하기
# page_num은 페이지번호, code는 카테고리, date는 날짜
page_num = 1
code = 101
date = 20200506
- 문자열은 더하면 이어붙이기가 된다
- 그러나, 문자열과 숫자는 더할 수 없다 -> 숫자를 str()함수를 이용해 문자열로 바꿔주는 작업을 해야한다.
url = 'https://news.naver.com/main/list.nhn?mode=LSD&mid=sec&sid1='+str(code)+'&date='+str(date)+'&page='+str(page_num)
print(url)
HTML 소스 코드 가져오기
- requests 패키지의 get 모듈 이용
- Header에 User Agent 정보를 넣어서 크롤링 차단 우회하기 (참고)
- 유저 정보를 추가한 경우에는 url 뒤에 headers=headers 추가
news = requests.get(url, headers=headers)
news.content
- 페이지 수, 카테고리, 날짜는 설정해야 함. urlist= []는 기사의 url을 저장하기 위한 빈 리스트
# 크롤링할 페이지 수, 카테고리, 날짜
def make_urllist(page_num, code, date):
# 각각 기사들이 가진 url을 저장하기 위한 빈 리스트를 하나 만들어놓는다.
urllist= []
- 1페이지부터 page_num까지 정해진 페이지만큼 같은 행위를 반복하기 때문에 range함수를 넣은 for문을 써준다
for i in ragne(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 라는 리스트로 저장
# type06_headline이라는 ul 태그 안에 li 태그 안에 dl 태그 안에 문서의 세부 정보 즉, 기사의 url 정보가 담겨 있었음
news_list = soup.select('.type06_headline li dl')
news_list.extend(soup.select('.type06 li dl'))
for line in news_list:
urllist.append(line.a.get('href'))
return urllist
- 헷갈리지 않게 code를 key, 실제 카테고리를 value로 가지는 dictionary를 만들자
- 이제 idx2word라는 딕셔너리를 통해서 이 코드 번호가 무슨 카테고리인지 바로 확인 가능
# 파이썬의 dictionarys는 선언 할 때는 'key' : 'value'의 형태로 선언
idx2word = {'101' : '경제', '102' : '사회', '103' : '생활/문화', '105' : 'IT/과학'}
# 선언 후에는 key 값을 넣으면 맵핑되어져 있는 value 값이 리턴됨
idx2word['101']
- 무언가를 저장하려면 반드시 빈 리스트 또는 빈 데이터베이스가 필요. ex) text_list = []
# 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]
- make_total_data 함수를 만들어서 make_urllist 함수와 make_data 함수를 호출하고 각 코드의 뉴스를 수집해서 데이터프레임에 저장한다.
df = make_total_data(2, code_list, 20200506)
음원 사이트 순위 크롤링
- 지니뮤직의 1~50위 곡 스크래핑하기
- 순위, 곡 제목, 가수 순으로 스크래핑
- BeautifulSoup4(bs4) 설치 후 BeautifulSoup 모듈 임포트
- BeautifulSoup 인스턴스 생성. 두 번째 매개변수는 분석할 분석기(parser)의 종류. 이 경우 'html.parser'
- soup.select 함수 활용해서 <tr> 태그 전체를 가져오고 for문을 이용해서 곡 정보를 하나씩 print
- selector 복사해서 바로 붙여 넣기
trs = soup.select('#body-content > div.newest-list > div > table > tbody > tr:nth-child(1)')
- tr:nth-child(1)은 tr이 붙은 요소 중에서 첫 번째 요소를 가져오라는 의미
- but, 모든 요소를 가져와야 하므로 tr만 남긴다
for tr in trs:
title = tr.select_one('td.info > a.title.ellipsis').text
print(title)
- tr 안에서 찾는 거니까 'td.info' 앞에 나온 건 중복되는 거니까 지워도 됨
- .text를 붙이면 a태그는 지워지고 문자에 해당하는 내용만 남는다.
- 결과값에서 공백이 너무 많을 때는 strip() 함수를 쓰면 공백이 다 지워짐. strip은 띄어쓰기 제거하는 함수
for tr in trs:
title = tr.select_one('td.info > a.title.ellipsis').text.strip()
print(title)
- 순위(rank)와 가수(artist)도 동일한 방식으로 하되, 순위에서 첫번째 숫자값만 남기려면 text[0:2]
for tr in trs:
title = tr.select_one('td.info > a.title.ellipsis').text.strip()
rank = tr.select_one('td.number').text[0:2].strip()
artist = tr.select_one('td.info > a.artist.ellipsis').text
print(title, rank, artist)
회고
KEEP | - 정리하면서 내 언어로 써야 이해됨 - 실습은 반드시 직접 해볼 것! |
PROBLEM | - 한 번에 다 들어야 흐름이 안 끊긴다. 시간을 들여서 한번에 몰아쳐야.. - 알파벳 철자 틀리는 경우가 은근 많다 - 코드 스니펫 복붙만 하지 말고 왜 그게 쓰이는지 이해해야 함 |
TRY | 참고자료로 제공되는 wiki 문서 검토 |

'Python' 카테고리의 다른 글
[데이터 분석] 3주차 강의노트 (1) 데이터프레임 (0) | 2022.07.09 |
---|---|
[데이터분석] 2주차 강의노트 (3) (0) | 2022.07.09 |
[데이터분석] 2주차 강의노트 (2) (0) | 2022.07.07 |
[데이터분석] 2주차 강의노트 (1) (0) | 2022.06.23 |