# 배경
오늘 반나절은 정말 끔찍했다. 10to5 동안 듣는 실시간 강의가 나를 무아지경으로 이끌었다. 평소에 나는 일부러 말을 느리게 하냐는 얘기를 듣는 편인데, 강사님이 말하는 속도가 나보다 두 배는 느렸기 때문에 지쳤었다. 그리고 강사님의 발성 이슈인지, 마이크 음질 이슈인지 전달이 거의 안 됐다. 영어 강의를 자막 없이 듣는 것처럼, 말씀하시는 내용이 하나의 문장이 아니라 띄엄띄엄 몇 개의 단어로만 귀에 들어왔다. 기본 문법조차 잘 모르는 언어인데, 무지성 클론 코딩만 하며 강의 시간을 버텼다.
그러던 중 점심시간에 메일을 확인해 보는데, 자료구조 교수님께서 전체 메일로 이번 학기의 목표가 섞인 말씀을 보내오셨다. 학기 중에 내주실 과제가 내가 익히 들어왔던 것보다 더 많은 것 같아 심장이 쪼렸다. 다행히 먹던 밥이 체하는 일은 없었다. 학교 온라인 교육 플랫폼 plato 에 공지사항이니 동영상이니 하나둘 올라오는걸 보니, 방학이 끝나간다는 사실이 한 자릿 수 d-day보다 더 실감나게 다가왔다. 그런데 이렇게 반나절을 무지성으로 보내고 있다는 걸 자각하니 기분이 끔찍했다.
5to9 동안 진행되는 실시간 강의 에서는 오늘 웹 스크래핑을 배웠다. 이 강의는 아무리 무미건조한 상태로 들어도 재미있게 들을 수 있어서 좋다. 아무튼 이때 배운 웹 스크래핑 방법을 이용해서, 티스토리와 관련된 무언가를 해보고 싶어졌다.
# 이 프로그램의 가치
저번 학기에 규칙적인 생활 패턴의 중요성을 깊이 체감했었다. 몇 시간 못 자고 시험을 치거나, 잠을 못 참아서 결석을 하거나.. 뼈아픈 실수들이었다. 물론 그 깨달음이 무색하게 지난 방학동안 아주 버라이어티한 수면 패턴으로 살아왔던 것 같다. 이 프로그램으로 내가 어느 시간대에 티스토리를 많이 하는지 확인해 보고, 새벽 시간에 많이 했다면 앞으로 경각심을 가질 수 있다는 점에서 의미가 있다.
# 소스 코드
# BeautifulSoup4, Selenium 라이브러리 설치 필요
# Chrome driver 설치 필요
# 필요한 모듈 호출
import requests
import time
import pandas as pd
from matplotlib import pyplot as plt
from bs4 import BeautifulSoup
from selenium import webdriver
# selenium 실행 옵션 (두 argument 중 택 1)
options = webdriver.ChromeOptions()
# options.add_argument('headless') # 화면을 띄우지 않고 백그라운드에서 진행할 경우
options.add_argument('window-size=1920x1080') # 일정 크기의 화면을 띄우고 진행할 경우
# 데이터를 가져올 웹 페이지 주소
my_tistory_url = 'https://star-sein.tistory.com/'
# selenium 이 제어할 chrome 을 실행
driver = webdriver.Chrome("/###/####/###/chromedriver", options= options)
# " " 안에 chromedriver 파일의 경로를 넣는다
# 데이터를 수집할 페이지로 이동
driver.get(my_tistory_url)
# 페이지의 html 코드를 저장
my_tistory_html = driver.page_source
# html 형식에 맞춰 파싱(parsing: 추후 이용하기 쉽도록 쪼개기)
my_tistory_soup = BeautifulSoup(my_tistory_html, 'html.parser')
# 게시글 업로드 시간이 들어갈 빈 리스트 생성
my_upload_times = []
# 업로드 시간 정보를 수집하고 페이지 하단의 NEXT 버튼을 누르기를 반복
while True:
my_tistory_html = driver.page_source
my_tistory_soup = BeautifulSoup(my_tistory_html, 'html.parser')
dates = my_tistory_soup.select('div.date')
for i in range(len(dates)):
str_dates = list(dates[i].stripped_strings)[0]
my_upload_times.append(list(str_dates)[-5:])
try: # class 이름이 '.next.no-more-next' 인 객체가 있을 경우 반복을 중단한다
driver.find_element_by_css_selector('.next.no-more-next')
break
except Exception: # 반복을 계속한다
driver.find_element_by_css_selector('.next ').click()
time.sleep(1)
# selenium 이 제어하는 chrome 을 종료
driver.quit()
# "년-월-일 시:분" 중 '시'만 slicing 해서 counting array 에 빈도 수를 저장
for i in range(len(my_upload_times)):
my_upload_times[i] = ''.join(my_upload_times[i])
list_time_count = [0 for i in range(24)]
for i in range(len(my_upload_times)):
hour = int(my_upload_times[i][:2])
list_time_count[hour] += 1
# counting array 를 인덱스명이 있는 Series 형태로 변환
s_times = pd.Series(list_time_count, index=[f'{i}~{i+1}' for i in range(24)])
# Series 를 막대 그래프로 시각화
plt.figure(figsize=(16,5))
x = s_times.index
y = s_times.values
plt.xlabel('Time')
plt.ylabel('Counts')
plt.bar(x, y, color='limegreen')
plt.xticks(rotation=45)
plt.show()
# 결과물
# 오늘 처음 해본 것
# 한 줄 후기
쪼렸던 심장이 활기차게 뛸 수 있었던 시간
'내가 가는 여정을 담는 그릇' 카테고리의 다른 글
흙이냐 벽돌이냐, 그것이 고민이로다. (0) | 2021.09.01 |
---|---|
답을 찾지 못한 날 (0) | 2021.08.27 |
Python과 C++ 그 사이에서 (0) | 2021.08.18 |
2021 부산코딩경진대회 (0) | 2021.08.15 |
[이스포츠 데이터분석 전문가 양성과정] 시작 (0) | 2021.08.11 |