간단한 크롤러 제작 요청이 와서 bs4 + Selenium 으로 파일을 만든 다음 exe 파일로 변환하여 전달을 했는데, 

실행할 시간대를 정할 수 있는 기능을 넣어달라는 요청이 왔다.

시간대를 정하게 하려면 프로그램 시작 때 프롬프트에 예약 실행 시간을 적어두게 할까 생각했는데

기본적으로 컴퓨터를 사용하지 않을 시간에 예약 기능을 쓸 것으로 생각되어

입력 실수로 인해 제대로 실행되지 않을 것을 감안해서 화면을 보면서 조정 가능하게 만드는게 더 나을 것 같다고 판단했다.

PyQt5 를 사용 해야 하나 생각했는데, 사용자가 UI에 큰 신경을 쓸 것 같지 않았고 무엇보다 레이아웃을 신경쓰면서

프로그램을 제작하기에는 예상한 것 보다 시간이 더 소요될 것 같아서 얼마 전에 활용해 본 tkinter 로 간단하게 제작하기로 결정했다.

 

먼저, 표기 해야하는 UI 목록을 생각해보자.

1. 프로그램 기본 윈도우 (제목, 사이즈 포함)
2. 현재 시간 표기 라벨 (프로그램이 정상적으로 실행되고 있는지 확인시켜주기 위한 용도)
3. 기능 실행 버튼
4. 예약 시간 선택 화면
5. 파일 선택 & 파일명 표기 (파일이 정상적으로 선택되었는지 확인하기 위한 용도)

1. 프로그램 기본 윈도우 생성하기

import tkinter

window = tkinter.Tk() # 초기화
window.title("Crawler") # 윈도우 제목 설정
window.geometry("300x475") # 윈도우 사이즈 설정

window.mainloop() # 시작

실행 결과

엄청 고전적인 스타일로 나오지만, 프로그램만 실행에 초점을 맞춰 최대한 꾸밈 없이 진행하도록 하자..

 

2. 현재 시간 표기 라벨

import tkinter

window = tkinter.Tk()
window.title("Crawler")
window.geometry("300x475")

# 진행 상황 표기 줄
status_label = tkinter.Label(window, text="시작 대기 중") # 라벨이 속할 화면과 텍스트 지정
status_label.pack(padx=20, pady=10) # 라벨을 화면에 넣기

# 현재 시간
clock_label = tkinter.Label(window, text="")
clock_label.pack(pady=10)

아직 시간은 표기되지 않고 있다.

시간 표기를 하기 위한 라벨 값에 빈 문자열 ("") 을 넣어둔 탓에, 프로그램이 실행된 초기 화면에는 시간값이 나오고 있지 않다.

이는 지속적으로 업데이트가 진행되어야 할 값이기 때문에, 버튼 클릭으로 동작하는 기능(웹 사이트 크롤링) 과 함께 하기 위해

잠시 비워두었다.

 

3. 기능 실행 버튼 추가

import tkinter

window = tkinter.Tk()
window.title("Crawler")
window.geometry("300x475")

def clock_update():
    current_time = time.strftime("%H:%M:%S") # 현재 시간 반환
    clock_label.config(text = "현재 시간 : {}".format(current_time)) # clock_label 값 업데이트
    window.after(1000, clock_update) # 1000ms (1초) 마다 실행


# 진행 상황 표기 줄
status_label = tkinter.Label(window, text="시작 대기 중")
status_label.pack(padx=20, pady=10)

# 현재 시간
clock_label = tkinter.Label(window, text="")
clock_label.pack(pady=10)

# 버튼 Method
button = tkinter.Button(window, command=clock_update, text="시작하기", width=200, height=10)
button.pack(padx=20, pady=25)
window.mainloop()

시작하기 버튼 클릭 시 현재 시간 반환

clock_update 함수로 1초마다 clock_label 값을 업데이트 하도록 구성하였고, 

tkinter.Button 의 속성 값 중 command 를 clock_update로 지정하여 버튼이 클릭되면 해당 함수를 사용하도록 구현하였다.

 

4. 예약 시간 선택 화면

import tkinter
from tktimepicker import AnalogPicker, constants # 라이브러리 설치 필요

window = tkinter.Tk()
window.title("Crawler")
window.geometry("300x475")

def clock_update():
    current_time = time.strftime("%H:%M:%S")
    clock_label.config(text = "현재 시간 : {}".format(current_time))
    window.after(1000, clock_update)
    
# 진행 상황 표기 줄
status_label = tkinter.Label(window, text="시작 대기 중")
status_label.pack(padx=20, pady=10)

# 현재 시간
clock_label = tkinter.Label(window, text="")
clock_label.pack(pady=10)

# 예약 시간
time_picker = AnalogPicker(window) # 아날로그 시계 추가
time_picker.pack(padx=20) # 윈도우 반영

# 버튼 Method
button = tkinter.Button(window, command=clock_update, text="시작하기", width=200, height=10)
button.pack(padx=20, pady=25)
window.mainloop()

아날로그 시계 적용된 화면

tktimepicker 에서 제공하는 AnalogPicker를 통해 간단하게 예약할 시간을 선택할 수 있는 시계를 넣어주었다.

 

5. 파일 선택 & 파일명 표기

import tkinter, sys
from tktimepicker import AnalogPicker
from tkinter import filedialog, messagebox

file = filedialog.askopenfilenames(initialdir="/", title="파일명 선택") # 파일 선택기 열기

#오류 발생 시 로직 - 파일 선택을 하지 않았을 경우
if not file:
    messagebox.showwarning("오류", "파일을 선택하세요")
    sys.exit()

window = tkinter.Tk()
window.title("Crawler")
window.geometry("300x500")

def clock_update():
    current_time = time.strftime("%H:%M:%S")
    clock_label.config(text = "현재 시간 : {}".format(current_time))
    window.after(1000, clock_update)
    
# 파일명 표기
file_name = tkinter.Label(window, text=file) # 선택된 파일면 표기
file_name.pack(padx=20) # 메인 화면에 반영

# 진행 상황 표기 줄
status_label = tkinter.Label(window, text="시작 대기 중")
status_label.pack(padx=20, pady=10)

# 현재 시간
clock_label = tkinter.Label(window, text="")
clock_label.pack(pady=10)

# 예약 시간
time_picker = AnalogPicker(window)
time_picker.pack(padx=20)

# 버튼 Method
button = tkinter.Button(window, command=clock_update, text="시작하기", width=200, height=10)
button.pack(padx=20, pady=25)
window.mainloop()

상단에 파일명 표기

프로그램을 시작하고 초기 화면에서 파일을 선택하게 할지, 프로그램 시작 전 파일을 선택하게 할지에 대한 고민을 했다.

전자의 경우에는 별도의 UI 구성이 필요 없지만

후자의 경우에는 버튼 > 라벨로 UI 변경 및 파일 선택 없이 프로그램을 실행하는 경우를 고려해야 한다.

실제 기능 (크롤러)을 사용할 인원은 한정되어있고, 크롤러 자체가 네이버 뉴스 크롤링 등 범용성을 염두해두고 제작한 것이 아니라

특정 페이지에 초점을 맞춰 제작한 것이므로, 예외 상황이 최대한 발생하지 않는 방향으로 제작했다. (기능 구현이 가장 급한 순서)

그 결과, 프로그램을 실행시키면, 파일 선택창이 가장 먼저 나오게 되고, 파일을 선택하면 그 후에 실행 예약창이 띄워지도록 구현하였다.

UI 구성은 이 정도로 마치고, 다음으로는 예약 시간에 맞춰 기능을 실행하도록 코드를 추가해야 한다.