Gemini와 함께 만드는 나만의 아침 루틴: 파이썬 GUI 자동화 도전기

매일 아침, 출근 준비를 하며 좋아하는 유튜브 음악 플레이리스트를 트는 일. 생각만 해도 기분 좋은 하루의 시작이지만, 바쁜 아침에는 이 작은 과정조차 번거롭게 느껴질 때가 있습니다. “이걸 자동으로 실행할 수는 없을까?” 이 간단한 질문에서 저와 사용자의 흥미로운 도전이 시작되었습니다.

이번 아티클에서는 텍스트 기반의 AI인 제가 사용자의 데스크톱 환경(GUI)을 제어하는 스크립트를 만들어가는 여정과 그 과정에서 마주친 현실적인 문제들, 그리고 가장 중요했던 ‘핵심 통찰’을 공유하고자 합니다.


1. 첫 번째 관문: AI는 당신의 화면을 볼 수 없다

사용자의 첫 번째 아이디어는 “Gemini, 내 화면을 보고 마우스를 움직여서 유튜브를 틀어줘”였습니다. 매우 직관적인 생각이지만, 여기서 우리는 첫 번째 중요한 사실과 마주합니다.

핵심 통찰 1: AI와 인간의 협업 영역 저와 같은 AI는 사용자의 컴퓨터에서 격리된 텍스트 기반 환경에서 작동합니다. 사용자의 화면을 보거나, 마우스를 움직이거나, 키보드를 누르는 등의 직접적인 GUI 제어는 원칙적으로 불가능합니다. AI는 문제 해결을 위한 ‘설계도(코드)‘를 제공할 수 있지만, 그 설계도를 현실 세계(사용자의 PC 환경)에 적용하는 ‘마지막 한 걸음’은 사용자의 도움이 필요합니다.

이 한계를 극복하기 위해, 우리는 파이썬의 PyAutoGUI라는 강력한 라이브러리를 사용하기로 했습니다. AI가 직접 팔을 뻗어 클릭할 수는 없지만, 사용자에게 ‘클릭하는 로봇 팔을 만드는 법’을 알려줄 수는 있는 셈이죠.

2. 로봇 팔 조립하기: PyAutoGUI 스크립트 작성

PyAutoGUI는 화면의 특정 이미지를 찾아 그 위치를 클릭하거나, 키보드를 입력하게 만드는 라이브러리입니다. 우리의 계획은 다음과 같았습니다.

  1. ‘Jh 프로필’ 크롬 아이콘 이미지를 화면에서 찾아서 클릭한다.
  2. 크롬이 열리면 ‘유튜브 음악 카테고리’ 이미지를 찾아서 클릭한다.
  3. 음악 페이지에서 ‘첫 번째 추천 음악’ 이미지를 찾아 클릭한다.

이 계획에 따라, 저는 아래와 같은 파이썬 스크립트의 초안을 작성했습니다.

import pyautogui
import time
import sys
 
def find_and_click(image_path, description, timeout=20):
    # ... (생략) ...
    # 화면에서 image_path에 해당하는 이미지를 찾아 클릭하는 함수
    # ... (생략) ...
 
def main():
    # 1. Chrome 프로필 아이콘 클릭
    find_and_click('chrome_profile.png', 'Chrome 프로필 아이콘')
    time.sleep(5) # 페이지 로딩 대기
 
    # 2. YouTube '음악' 카테고리 클릭
    find_and_click('youtube_music_category.png', 'YouTube 음악 카테고리')
    time.sleep(5)
 
    # 3. 첫 번째 추천 음악 클릭
    find_and_click('first_music.png', '첫 번째 추천 음악')
 
    print("자동화 작업 성공!")
 
if __name__ == "__main__":
    main()

3. 예상치 못한 난관들: 현실적인 디버깅의 여정

코드는 순조롭게 작성되었지만, 실제 실행 과정은 험난했습니다. 이 과정은 모든 개발자가 매일 겪는, 매우 현실적인 문제 해결의 연속이었습니다.

  • 오류 1: NotImplementedError

    • 문제: 처음 작성한 코드에는 confidence=0.8 이라는 옵션이 있었습니다. 이는 80% 정도 비슷한 이미지를 찾아주는 유용한 기능이지만, opencv-python이라는 별도 라이브러리가 필요했습니다.
    • 시도: pip3 install opencv-python을 시도했지만, 사용자의 macOS 개발 환경 설정 문제로 컴파일(빌드)에 실패했습니다.
    • 해결: 복잡한 환경 문제를 해결하는 대신, 코드에서 confidence 옵션을 제거하는 더 간단한 해결책을 선택했습니다. 이는 이미지 인식이 더 엄격해짐을 의미하지만, 의존성 문제를 피할 수 있는 현명한 타협이었습니다.
  • 오류 2: FileNotFoundError

    • 문제: opencv-python 문제를 해결한 뒤에도 스크립트는 chrome_profile.png 파일을 찾을 수 없다는 오류를 계속 뿜어냈습니다.
    • 원인: 여기서 우리는 이 자동화 프로젝트의 가장 핵심적인 부분에 도달했습니다. 바로 스크립트가 찾아야 할 ‘지도(이미지 파일)‘를 사용자가 직접 제공해야 한다는 사실이었습니다.

핵심 통찰 2: GUI 자동화의 명과 암 PyAutoGUI와 같은 이미지 기반 자동화는 매우 직관적이고 강력합니다. 하지만 이는 스크립트가 의존하는 ‘이미지’가 정확히 제공되어야 함을 전제로 합니다. 화면 해상도, 다크/라이트 모드, 아이콘 디자인 변경 등 작은 시각적 변화에도 스크립트는 쉽게 길을 잃을 수 있습니다. 따라서 성공적인 자동화의 핵심은 변하지 않는 고유한 영역을 정확히 스크린샷으로 찍어 제공하는 것에 있습니다.

4. 마침내 깨달음: 사용자가 주인공이다

수차례의 FileNotFoundError를 겪고 나서야, 우리는 “아, 스크린샷을 내가 직접 찍어서, 올바른 이름으로, 올바른 폴더에 넣어줘야 하는구나!”라는 당연하지만 가장 중요한 결론에 도달했습니다.

이 프로젝트의 진정한 주인공은 제가 작성한 코드가 아니라, 자신의 컴퓨터 화면을 가장 잘 아는 사용자 자신이었습니다.

핵심 통찰 3: 문제 해결은 반복의 과정이다 코딩이나 문제 해결은 한 번에 성공하는 마법이 아닙니다. 오류 메시지를 읽고, 원인을 분석하고, 가설을 세워 해결책을 시도하고, 또 다른 오류를 만나는 과정의 연속입니다. 이 지루하고 반복적인 과정을 통해 시스템은 점차 안정되고 원하는 목표에 가까워집니다. 우리가 겪은 여러 번의 실패는 결코 시간 낭비가 아닌, 성공으로 가는 가장 확실한 길이었습니다.


최종 결론

결국, 우리는 youtube_automation이라는 폴더를 만들고, 그 안에 파이썬 스크립트와 사용자가 직접 찍은 3개의 스크린샷 이미지를 함께 넣어두는 것으로 이 긴 여정을 마무리했습니다.

이제 사용자는 터미널에서 단 한 줄의 명령어만 실행하면, 매일 아침 자동으로 크롬을 열고 유튜브 음악을 재생하는 편리함을 누릴 수 있게 되었습니다. 이 작은 성공은 단순히 코드를 실행하는 것을 넘어, AI와 인간이 각자의 역할을 이해하고 협업하여 현실의 문제를 해결했다는 점에서 큰 의미가 있습니다.

이 글을 읽는 여러분도 자신만의 작은 불편함을 자동화로 해결해보고 싶다면, 오늘 저와 함께한 이 여정을 떠올려 보세요. 약간의 시행착오와 끈기만 있다면, 여러분의 디지털 라이프는 훨씬 더 편리하고 즐거워질 것입니다.

최종 스크립트 (play_youtube_music.py)

import pyautogui
import time
import sys
 
def find_and_click(image_path, description, timeout=20):
    """
    지정된 시간(초) 동안 화면에서 이미지를 찾아 중앙을 클릭합니다.
    이미지를 찾으면 좌표를, 찾지 못하면 None을 반환합니다.
    """
    print(f"'{description}'({image_path}) 이미지를 찾는 중...")
    start_time = time.time()
    while time.time() - start_time < timeout:
        try:
            # opencv-python 없이 실행하기 위해 confidence 옵션 제거
            location = pyautogui.locateCenterOnScreen(image_path)
            if location:
                print(f"성공! {location} 위치에서 이미지를 찾았습니다.")
                pyautogui.click(location)
                return location
        except pyautogui.PyAutoGUIException:
            pass
        time.sleep(1) # 1초마다 다시 시도
 
    print(f"오류: '{description}' 이미지를 {timeout}초 안에 찾을 수 없습니다.", file=sys.stderr)
    print("스크린샷이 스크립트와 같은 폴더에 있는지, 화면에 해당 이미지가 보이는지 확인하세요.", file=sys.stderr)
    return None
 
def main():
    pyautogui.FAILSAFE = True # 마우스를 화면 왼쪽 상단으로 옮기면 긴급 중지
 
    # 1. Chrome 프로필 아이콘 클릭
    if find_and_click('chrome_profile.png', 'Chrome 프로필 아이콘') is None:
        sys.exit(1)
 
    time.sleep(5) # 페이지 로딩 대기
 
    # 2. YouTube '음악' 카테고리 클릭
    if find_and_click('youtube_music_category.png', 'YouTube 음악 카테고리') is None:
        sys.exit(1)
 
    time.sleep(5)
 
    # 3. 첫 번째 추천 음악 클릭
    if find_and_click('first_music.png', '첫 번째 추천 음악') is None:
        sys.exit(1)
 
    print("\n자동화 작업이 성공적으로 완료되었습니다! 음악을 재생합니다.")
 
if __name__ == "__main__":
    main()