💬 스파르타 코딩클럽에서 11주 완주챌린지가 끝나고 힙한코딩이라는 이벤트 강의에 신청했다.
48시간 안에 강의를 듣고 작품을 완성해서 제출하면 되는데, 추첨을 통해 엄청난 상품을 준다고 한다.
나는 맥북을 노리며 힙코를 시작했다..!🤗

💬 4개의 코딩 미션중에 1개를 선택해서 미션을 완수하면 되는데, 나는 python을 다루는 [모아라] 미션을 선택했다! 가장 추천해주시는 미션이기도 했고 11일 챌린지 하면서도 python을 조금 더 다뤄봤으면 싶었어서 선택했다.
미션을 선택하고 신청하기를 누르자 마자 48시간 타이머가 시작되었다!
48시간동안 열심히 미션을 완수해보자 아자아자👊🏻👊🏻
⭐️ TIP
✔ = : 대입의 의미
✔ == : 같다의 의미
✔ != : 같지않다의 의미
✔ '' 작은따옴표가 붙는 것은 문자열이다. (아닌 것은 모두 변수!)
✔ ctrl + / : 주석처리
✔ 변수이름은 직관적으로 모든 사람이 알 수 있도록 짓는 것이 좋다.
a = 3 # 3을 a에 넣는다
b = a # a를 b에 넣는다
a = a + 1 # a+1을 다시 a에 넣는다
num1 = a*b # a*b의 값을 num1이라는 변수에 넣는다
num2 = 99 # 99의 값을 num2이라는 변수에 넣는다
💡 리스트형
✔ 순서가 중요함.
✔ 0부터 시작한다. 0부터 자료를 담아두고 0부터 자료를 뽑아씀.
✔ list는 숫자로 찾음.
# list형
a_list = ['사과', '감', '배']
b_list = ['영희', '철수',['사과','감']]
a_list.append('수박')
print(a_list)
# 결과
['사과', '감', '배', '수박']
💡 딕셔너리형
✔ key:value -> key로 값을 담아두고 key로 값을 뽑아내는 방식으로 순서가 중요하지 않음
✔ 딕셔너리는 key값으로 찾음.
# dictionary형
a_dict = {'name':'bob','age':'24'}
a_dict['height'] = 178
print(a_dict)
# 결과
{'name': 'bob', 'age': '24', 'height': 178}
✔ 파이썬은 매우 직관적으로, 내용이 하나의 탭(Tab)으로 묶인다. -> 그러므로 Tab이 매우 중요!
✔ if/else 로 구성
# 조건문
age = 24
if age > 20:
print('성인입니다')
else:
print('청소년입니다')
# 결과
성인입니다
✔ 반복문은 리스트를 하나씩 빼서 쓰는 것! -> 리스트의 길이만큼 반복하게 됨
✔ for __ in 으로 구성
# 반복문
fruits = ['사과','배','배','감','수박','귤','딸기','사과','배','수박']
for fruit in fruits:
print(fruit)
# 결과
사과
배
배
감
수박
귤
딸기
사과
배
수박
✔ 반복문 안에 조건문이 들어가 있는 경우가 굉장히 많다!
# 반복문 예제 ( 반복문 안에 조건문이 들어간 경우 )
people = [{'name': 'bob', 'age': 20},
{'name': 'carry', 'age': 38},
{'name': 'john', 'age': 7},
{'name': 'smith', 'age': 17},
{'name': 'ben', 'age': 27}]
for person in people:
if person['age'] > 20:
print(person['name'])
# 결과 -> people의 list가 하나씩 돌면서 age가 20 초과인 person의 name값만 출력됨.
carry
ben
💡 .split('____') : 문자열 쪼개기
# 문자열 쪼개기 (.split)
myemail = 'sparta@naver.com'
result = myemail.split('@')
print(result)
# 결과 -> myemail을 @ 기준으로 쪼개어 출력
['sparta', 'naver.com']
💡 .replace('__','__') : 문자 바꾸기
# 문자 바꾸기 (.replace)
myemail = 'sparta@naver.com'
result = myemail.replace('naver','gmail')
print(result)
# 결과
sparta@gmail.com
❔ 패키지, 라이브러리
✔ 남이 만들어 놓은 코드이다.
✔ 패키지 : 모듈(일종의 기능들 묶음)을 모아 놓은 단위
✔ 라이브러리 : 패키지의 묶음
❔ 가상환경(venv)
✔ 프로젝트별 공구함 -> 즉 여기다가 라이브러리 갖다 쓰고 깔때도 여기다 깔아!의 개념정도로만 이해
✔ file - setting - python interpreter - +버튼 - 패키지 검색 - install package
.png)
.png)
.png)
💡 dload 패키지 설치
✔ url을 넣으면 이미지를 다운 받게 해주는 패키지
import dload
dload.save("https://spartacodingclub.kr/static/css/images/ogimage.png")
▶️ import : dload라는 패키지를 갖다 쓰겠다~
❔ 웹 스크래핑(web scraping)
✔ 웹 페이지에서 우리가 원하는 부분의 데이터를 수집해오는 것
💡 selenium 패키지 설치
✔ 브라우저를 자동 제어하는 패키지
💡 BeautifulSoup4 패키지 설치
✔ 브라우저가 보고 있는 것 중에서 내가 원하는 것을 솎아내는 패키지
💡 크롤링 기본 세팅 가져오기
# 크롤링 기본 세팅
from bs4 import BeautifulSoup
from selenium import webdriver
import time
driver = webdriver.Chrome('chromedriver') # 웹드라이버 파일의 경로
driver.get("https://search.daum.net/search?w=img&nil_search=btn&DA=NTB&enc=utf8&q=%EC%95%84%EC%9D%B4%EC%9C%A0")
time.sleep(5) # 5초 동안 페이지 로딩 기다리기
req = driver.page_source
# HTML을 BeautifulSoup이라는 라이브러리를 활용해 검색하기 용이한 상태로 만듦
# soup이라는 변수에 "파싱 용이해진 html"이 담긴 상태가 됨
# 이제 코딩을 통해 필요한 부분을 추출하면 된다.
soup = BeautifulSoup(req, 'html.parser')
###################################
# 이제 여기에 코딩을 하면 됩니다!
###################################
driver.quit() # 끝나면 닫아주기
💡 Beautifulsoup4 이용하기
✔ select : 여러개 솎아내기
✔ select_one : 하나만 솎아내기

▶️ 크롬 개발자 도구를 참고하여 원하는 태그에서 copy - copy selector로 복사
soup = BeautifulSoup(req, 'html.parser')
thumbnails = soup.select('#imgList > div > a > img') #이렇게 생긴 태그를 여러개 솎아내기
💡 dload 이용해서 이미지 저장하기
soup = BeautifulSoup(req, 'html.parser')
thumbnails = soup.select('#imgList > div > a > img')
i = 1
for thumbnail in thumbnails:
image = thumbnail['src']
dload.save(image,f'image/{i}.jpg') #image를 저장하는데 파일명을 (1,2,3 ~).jpg로 저장함
i += 1
▶️ 좋아하는 연예인 이미지 크롤링해서 저장하기
import dload #dlad 이용
from bs4 import BeautifulSoup #bs4 이용
from selenium import webdriver #selenium 이용
import time
driver = webdriver.Chrome('chromedriver')
driver.get("https://search.daum.net/search?nil_suggest=btn&w=img&DA=SBC&q=%EB%A1%9C%EB%B2%84%ED%8A%B8+%EB%8B%A4%EC%9A%B0%EB%8B%88+%EC%A3%BC%EB%8B%88%EC%96%B4") # 여기에 URL을 넣어주세요
time.sleep(5)
req = driver.page_source
soup = BeautifulSoup(req, 'html.parser')
roberts = soup.select('#imgList > div > a > img') #해당 태그를 여러개 솎아내기
i = 1
for robert in roberts:
image = robert['src']
dload.save(image,f'image_hw/{i}.jpg')
i += 1
driver.quit() # 끝나면 닫아주기
▶️ 결과

💬 soup.select() 다음에 반복문을 돌리지 않고 print부터 해보는 바람에 에러가 떴다. 에러가 왜 뜨는지 알아보려고 뻘짓을 좀 했다..... 뻘짓을 하다가 알아낸 오류의 원인 -> select로 데이터를 여러개 뽑았으면 반복문을 돌려야지 이 바보야...! 아직 반복문이 언제 필요한지 확실하게 알지 못해서 이런 실수를 한거 같다. 이 에러 덕분에 5분이면 끝날 것을 10분 넘게 잡아먹었지만...ㅎ 난 초보니까 실수해도 괜찮아!!!
2주차(2021/09/24)
💬 2주차에는 기사를 스크래핑해와서 엑셀에 넣고 이메일까지 보내는 것을 배운다고 한다. 이것을 업무자동화에도 이용할 수 있다고 하는데..... 업무자동화 말로만 들어봤지 내가 해볼 수 있을거라고는 상상도 못했는데! 이것만 듣는다고 완벽하게 업무자동화를 구현해낼 수 있는 것은 아니겠지만 업무자동화라는 단어 자체가 뭔가 간지나고.... 공부하고 싶어지는 욕구가 생긴다💪
💡 .text : 텍스트만 가져올때
.png)
from bs4 import BeautifulSoup
from selenium import webdriver
driver = webdriver.Chrome('chromedriver')
url = "https://search.naver.com/search.naver?where=news&sm=tab_jum&query=추석"
driver.get(url)
req = driver.page_source
soup = BeautifulSoup(req, 'html.parser')
articles = soup.select('#main_pack > section.sc_new.sp_nnews._prs_nws > div > div.group_news > ul > li') #여기에서 ul 안에 있느 li들을 가지고 와라
for article in articles:
title = article.select_one('div.news_wrap api_ani_send > div.news_area > a.news_tit')
url = article.select_one('div.news_wrap api_ani_send > div.news_area > a')['href']
comp = article.select_one('a.info.press').text.split(' ')[0].replace('언론사','') # company : 신문사이름 # split : 띄어쓰기를 기준으로 앞에거만 가져오기, replace : 언론사를 없애기
print(title, url, comp)
driver.quit()
# 결과
None
None
None
None
None
None
None
None
None
None
💬 기사 제목만 크롤링 해오는데 자꾸 none만 떠서 미쳐버리는줄..... 강의에서는 구조가 되게 간단하던데 내가 보고있는 화면에서는 더 복잡한 구조로 되어 있는지! 난 코린인데 말이야!!! 결국은 우선 포기했다.... 시간안에 끝내야 되니까 일단은 넘어가는 걸로 타협..^^
💡 openpyxl 패키지 설치하기
✔ 파이썬으로 엑셀 파일을 읽고 쓰는 패키지
# openpyl
from openpyxl import Workbook
wb = Workbook()
ws1 = wb.active
ws1.title = "articles"
ws1.append(["제목", "링크", "신문사"])
ws1.append(["1", "2", "3"])
wb.save(filename='articles.xlsx')

💬 이렇게 하면 엑셀에 값이 저장된다.
⭐️ 주의
✔ 이메일 계정 2단계 인증 -> 해제되어있어야 함!
✔ 보안 수준이 낮은 앱 -> 해제되어 있어야 함!
💡 이메일 보내기 시작코드
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email import encoders
# 보내는 사람 정보
me = "보내는사람@gmail.com"
my_password = "비밀번호"
# 로그인하기
s = smtplib.SMTP_SSL('smtp.gmail.com')
s.login(me, my_password)
# 받는 사람 정보
you = "받는사람@아무_도메인"
# 메일 기본 정보 설정
msg = MIMEMultipart('alternative')
msg['Subject'] = "제목"
msg['From'] = me
msg['To'] = you
# 메일 내용 쓰기
content = "메일 내용"
part2 = MIMEText(content, 'plain')
msg.attach(part2)
# 메일 보내고 서버 끄기
s.sendmail(me, you, msg.as_string())
s.quit()
💡 여러사람에게 각각 이메일 보내기
## 여러사람
# 받는 사람 정보
emails = ['받는사람@naver.com', '받는사람@naver.com']
for you in emails:
# 메일 기본 정보 설정
msg = MIMEMultipart('alternative')
msg['Subject'] = "이것이 제목이다."
msg['From'] = me
msg['To'] = you
# 메일 내용 쓰기
content = "추석에 뭐해?"
part2 = MIMEText(content, 'plain')
msg.attach(part2)
# 메일 보내고 서버 끄기
s.sendmail(me, you, msg.as_string())
s.quit()
💬 여러사람에게 보내기 할때 for문으로 돌리기 때문에 tab을 해주는데 처음에 s.quit()까지 tab으로 묶어버려서 에러가 남. s.quit()는 서버끄기 코드인데, 왜 tab으로 묶여있으면 안되는 건지? for문이 돌면서 메일을 보내고 끝나야 하는데 반복문 안에 끄는코드가 들어가있어서 문제가 되는 것으로 생각해본다.
▶️ 썸네일을 포함해 기사 크롤링해서 자신에게 메일 보내기
from openpyxl import Workbook
from bs4 import BeautifulSoup
from selenium import webdriver
driver = webdriver.Chrome('chromedriver')
url = "https://search.naver.com/search.naver?where=news&sm=tab_jum&query=추석"
driver.get(url)
req = driver.page_source
soup = BeautifulSoup(req, 'html.parser')
articles = soup.select('#main_pack > section.sc_new.sp_nnews._prs_nws > div > div.group_news > ul > li') #여기에서 ul 안에 있느 li들을 가지고 와라
wb = Workbook()
ws1 = wb.active
ws1.title = "articles"
ws1.append(["제목", "링크", "신문사", "썸네일"])
for article in articles:
title = article.select_one('a.news_tit').text
url = article.select_one('a.news_tit')['href']
comp = article.select_one('a.info.press').text.split(' ')[0].replace('언론사','') # company : 신문사이름 # split : 띄어쓰기를 기준으로 앞에거만 가져오기, replace : 언론사를 없애기
thumnail = article.select_one('a.dsc_thumb > img')['src']
ws1.append([title,url,comp,thumnail])
driver.quit()
wb.save(filename='articles.xlsx')
💬 지난번 기사 title, url, comp를 크롤링 해올때 복잡한 태그 구조를 어떻게 해야 할지 몰라서 넘어갔었는데, 가장 세부 태그만을 끌고 와서 넣어주니까 크롤링이 잘 되었다!! 그런데 태그구조 전체를 긁어오는 것이 아닌 세부태그만을 긁어왔을 때 단점이 있을지는 모르겠다...긁적...🙄
일단은 태그랑 class를 매칭하는 방식으로 긁어오는 것 같은데, 이 구조가 다 다르다 보니까 크롤링을 여러번 하다보면 감이 오겠지 싶다.
3주차(2021/09/24)
💬 2주차에 이어서 3주차까지 한번에 끝내버리기로 마음을 먹고 start-! 힙코미션 완수 가즈아
3주차에는 카톡내용으로 워드 클라우드를 만들어본다고 하는데 어떤 카톡방을 열어볼지 벌써 고민이군...🤔 재미있을거 같당!
f = open("test.txt", "w", encoding="utf-8")
f.write("안녕, 스파르타!")
f.close()
💡 여러줄 쓰기
f = open("test.txt", "w", encoding="utf-8")
f.write("안녕, 스파르타!\n")
f.write("안녕, 스파르타!\n")
f.write("안녕, 스파르타!\n")
f.close()
# 결과
안녕, 스파르타!
안녕, 스파르타!
안녕, 스파르타!
💬 여러줄을 쓰고 싶을때는 줄바꿈 이스케이프 코드 \n을 넣어준다고 한다.
💡 반복문 이용하기
f = open("test.txt", "w", encoding="utf-8")
f.write("안녕, 스파르타!\n")
for i in [1,2,3,4,5]:
f.write(f"{i}번째 줄이에요\n")
f.close()
# 결과
안녕, 스파르타!
1번째 줄이에요
2번째 줄이에요
3번째 줄이에요
4번째 줄이에요
5번째 줄이에요
💬 (f"{i}") 전에 한번 봤던거 같은데도 많이 낯선 이친구..... 내 머릿속에 지우개가 들었나... 이래서 복습을 해야된다. i에 값들이 하나씩 들어가도록 반복할 때 f와 중활호{}를 써준다 복습!!
with open("test.txt", "r", encoding="utf-8") as f:
lines = f.readlines()
for line in lines:
print(line)
# 결과
안녕, 스파르타!
1번째 줄이에요
2번째 줄이에요
3번째 줄이에요
4번째 줄이에요
5번째 줄이에요
💬 프린트하면서 엔터가 들어가는데, 이걸 붙이기 위해서
text = ''
with open("test.txt", "r", encoding="utf-8") as f:
lines = f.readlines()
for line in lines:
text += line
print(text)
# 결과
안녕, 스파르타!
1번째 줄이에요
2번째 줄이에요
3번째 줄이에요
4번째 줄이에요
5번째 줄이에요
💬 이렇게 빈 텍스트에 문자열을 더하는 과정으로 해볼 수도 있다는데 이게 무슨말이지.......
💡 사전 준비
💬 카카오톡 대화내용 내보내기를 통해 kakaotalk.txt 파일을 만들어 텍스트 파일 읽기를 한다. 나는 도른자들이라는 이름의 찐친들과의 카톡방을 탐험하기로 했다. 내용이 걱정이되지만... 제일 재미있을거 같아서!
💡 wordcloud 패키지 설치
💡 한글폰트 찾기
import matplotlib.font_manager as fm
# 이용 가능한 폰트 중 '고딕'만 선별
for font in fm.fontManager.ttflist:
if 'Gothic' in font.name:
print(font.name, font.fname)
# 결과
Malgun Gothic C:\Windows\Fonts\malgun.ttf
Franklin Gothic Medium Cond C:\WINDOWS\Fonts\FRAMDCN.TTF
HYGothic-Medium C:\WINDOWS\Fonts\H2GTRM.TTF
Franklin Gothic Medium Cond C:\Windows\Fonts\FRAMDCN.TTF
Franklin Gothic Demi C:\WINDOWS\Fonts\FRADMIT.TTF
Franklin Gothic Demi C:\Windows\Fonts\FRADMIT.TTF
Yu Gothic C:\Windows\Fonts\YuGothB.ttc
Franklin Gothic Book C:\WINDOWS\Fonts\FRABK.TTF
HYGothic-Extra C:\Windows\Fonts\H2GTRE.TTF
Process finished with exit code 0
💬 마음에 드는 폰트 복사해두기
💡 워드클라우드 만들기
from wordcloud import WordCloud
# font_path에 한글폰트 복사 붙여넣기
wc = WordCloud(font_path='C:/WINDOWS/Fonts/GOTHICB.TTF', background_color="white", width=600, height=400)
wc.generate(text)
wc.to_file("result.png")
💬 이때 윈도우는 한글폰트 붙여넣을때 역슬래시를 /로 바꿔줘야함!
from wordcloud import WordCloud
text = ''
with open("kakaotalk(도른자들).txt", "r", encoding="utf-8") as f:
lines = f.readlines()
for line in lines:
text += line
wc = WordCloud(font_path='C:/Windows/Fonts/H2GTRE.TTF', background_color="white", width=600, height=400)
wc.generate(text)
wc.to_file("result.png")
💬 이 상태로 run하면 보낸사람 이름까지 모두 잡혀버리기때문에 데이터 클렌징 과정이 필요하다!!
❔ 데이터 클렌징
✔ 자료에서 불완전하거나, 비정확하거나, 관련 없는 부분을 찾아 삭제하거나 수정하는 것
💡 톡방 이름과 저장 날짜 없애주기
for line in lines[2:]: # 2번째줄부터 시작
text+=line
💡 이름, 시간 제외하고 대화내용만 가져오기
for line in lines:
if '] [' in line:
text += line.split('] ')[2]
💬 split을 사용해서 ]을 기준으로 대화내용에 해당하는2번째만 불러온다는 생각을 해내는 거 자체가 아직은 신기하다....
💡 추가적으로 ㅋ,ㅠ,이모티콘 등의 문자열 제거하기
✔ .repalce('____','') 이용하기
for line in lines[5:]:
if '] [' in line: # 시스템 메세지를 없애기 위한 과정
text += line.split('] ')[2].replace('ㅋ','').replace('ㅠ','')
💬 원하는 모양으로 만드려면 어떤 모양이든 흰색 배경의 이미지가 있으면 가능하며, 이미지의 경계가 뚜렷할 수록 잘 만들어진다고 하니 참고!!
💡 마스킹된 워드 클라우드 만들기
from PIL import Image
import numpy as np
mask = np.array(Image.open('cloud.png'))
wc = WordCloud(font_path=font_path, background_color="white", mask=mask) # font_path에 사용할 한글폰트를 넣기
wc.generate(text)
wc.to_file("result_masked.png")
▶️ 결과

▶️ 나만의 워드클라우드 만들기

💬 나의 워드클라우드를 만들고 드는 생각은 욕이 많네...뻘쭘; 🙄🙄🙄🙄