Home [Python] Automation - 1. GUI
Post
Cancel

[Python] Automation - 1. GUI

‘자동화’라는 것을 해보자. Python으로 하고 window 운영체제 한정이다.

보통 자동화라고 하면 단순 반복스러운 일들을 클릭 한번으로 화면이 휙휙 바뀌면서 막 컴퓨터가 알아서 해주는 그런 움짤들이 떠오른다. 좀 있어보이게 그런 것도 한번 해보자.

따지고보면 컴퓨터한테 어떤 일을 시킨다는 입장에서 정도의 차이야 있겠지만 모든 코딩은 자동화라고도 할수있지 않나 싶다. 구글링 해보니 자동화의 의미에 대해 써놓은 글도 있다.

1. Intro

먼저 다른 포스팅과는 다르게 이번에 다룰 내용들에는 컴퓨터 용어가 좀 많이 나온다. 본격적인 자동화를 시작하기 전에 몇 가지 용어들을 정리해보자. 구글링과 눈치로 대충 느낌만 알고있는 그런 용어들이라는 점 감안해주길 바란다. 다룰 용어에 대한 자세한 정의가 필요하다면 따로 찾아보기를 추천한다.

이번 포스팅에서 다룰 Python을 활용한 자동화는 크게 2가지로 분류할 수 있다. 하나는 GUI라는 것을 제어하는 것이고 다른 하나는 COM Object를 활용하는 것이다. 여기서는 GUI 자동화를 해본다.

GUI는 Graphical User Interface의 약자다. 관련한 자세한 자료는 여기여기를 읽어보자. 간단하게 사람이 컴퓨터로 일을 할 때 마우스와 키보드를 이용해서 화면에 뜬 아이콘이나 메뉴를 클릭하고 문자를 입력하고 하는 것을 생각하면 된다. GUI자동화는 이러한 마우스와 키보드의 동작을 미리 짜놓은 코드로 제어하는 것이다. 이러한 제어에 pyautogui라는 python 모듈이 쓰인다.

처음 이 모듈의 존재를 알았을 때 바로 게임매크로를 만들었었다. 핸드폰 게임이었는데 Android 에뮬레이터로 컴퓨터에서 주로 했었다. 게임 내 각 메뉴 이미지를 하나하나 캡쳐해서 저장해놓고 특정조건이 만족되면 특정 메뉴를 클릭하고 다음 단계를 진행하는 식의 코드였다. 게임이 자꾸 업데이트 되면서 메뉴 모양이 바뀌어 귀찮아서 그만뒀었지만 한동안 잘 가지고 놀았었다. 그래도 게임매크로는 왠만하면 만들지 말자..

경험상 원하는 자동화 기능구현이 쉽지만 얕은 수준에서의 자동화다. 못하는 읻도 많고 오류도 많다고 까지 말하고 싶기도 한데, 이건 코드를 짜는 사람 능력따라서도 다른거라서 쉽게 단정짓지는 못하겠다.

2. GUI

미리 짜놓은 코드대로 python이 키보드와 마우스를 움직여주는 GUI 자동화를 해보자. 슉슉 움직이는 움짤좀 만들어본다.

2.1. Pyautogui

pyautogui라는 모듈이 필요하다. 없다면 터미널에서 아래명령어로 설치해준다. 터미널이 뭔지 모듈 설치는 뭔지는 여기를 참고하자.

1
pip install pyautogui

pyautogui 공식 문서보다는 여기가 좀 더 설명이 쉬운거 같다. 여기코드를 배껴다 쓴다. pyautogui로는 아래 일들을 수행할 수 있다.

  • screen(모니터) size 확인
  • 마우스움직임 제어 (움직임, 드래그, 클릭, 더블클릭, 우클릭, 스크롤 등)
  • 스크린샷 및 RGB 정보 확인
  • 모니터 화면내 특정 이미지 위치 확인
  • 키보드조작 (특정 문자열 작성, 특정 문자 입력 전송)

대충 열거하자면 이정도다.

어찌됬든 여기서는 그림판을 실행하고 특정문양을 그리는 일을 pyautogui로 해본다. 전혀 의미없어 보이는 일이지만 이런거 조금 연습해보면 내가 하고싶은 진짜 자동화 해볼 수 있다.

2.2. Step by Step

하나씩 단계를 생각해보자. 여기서 하려는건 그림판에 특정 그림을 그리는 작업을 하려고 한다. 아래 단계대로 생각해보자.

  • 그림판 프로그램 실행
  • 원하는 모양 그리기

그림판 프로그램 실행부분만 더 세분화 해보자.

  • 그림판 프로그램 실행
    • 윈도우키를 누른다
    • 그림판 프로그램을 찾는다 (시작화면에서 paint라고 친다)
    • 그림판 프로그램을 실행한다 (Enter키를 누른다)

사람이 마우스와 키보드를 동작하는 순서 그대로를 차례대로 코드로 구현하면 된다. GUI 제어에서 조금 조심해야 할 점은 하나의 동작과 동작 사이에 적당한 시간차이를 두어야 한다는 점이다. 우리가 어떤 프로그램을 실행하라고 마우스로 더블클릭을 하든 엔터를 누르든간에 바로 열리는 것은 아니고 아주 약간의 지연시간이 있다. 이때 쓰는 코드는 time 모듈의 sleep()이다.

아래 코드를 실행하면 그림판이 실행된다.

1
2
import pyautogui as pg
import time
1
2
3
4
5
6
7
8
time.sleep(1)
pg.press("winleft")

time.sleep(1)
pg.typewrite("paint")

time.sleep(1)
pg.press("Enter")

time.sleep(1)은 여기에서 1초를 쉬라는 얘기다. 각 단계당 시간을 줄일수 있지만 너무 줄이면 다음단계가 실행되기 위한 화면이 뜨기전에 명령이 전달되면서 내가 원하는 동작이 구현되지 않을 수 있다. 1초정도는 기다리자.

paint는 그림판 프로그램의 영어 이름이다. 한글을 입력하는 방법은 좀 복잡한 것 같다. 여기를 참고하자.

마지막에는 시작메뉴에서 그림판이 뜬 상태에서 Enter를 누른다. 이후에는 그림판 프로그램이 화면에 뜰 것이다.

남은 일은 모니터 화면에 실행된 그림판 프로그램에 특정 모양을 마우스로 그리는 것이다. 아래 단계를 생각해본다.

  • 원하는 모양 그리기
    • 모니터에 실행된 그림판 프로그램 빈 화면에 마우스를 댄다
    • 원하는 모양을 그리도록 드래그 한다

코드는 합쳐서 아래처럼 쓸 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
time.sleep(1)
pg.press("winleft")

time.sleep(1)
pg.typewrite("paint")

time.sleep(1)
pg.press("Enter")

time.sleep(1)
pg.click(50, 620)
distance = 300
change = 20
while distance > 0:
    pg.drag(distance, 0, duration=0.2)
    distance = distance - change
    pg.drag(0, distance, duration=0.2)
    pg.drag(-distance, 0, duration=0.2)
    distance = distance - change
    pg.drag(0, -distance, duration=0.2)

pg.click(50, 620)은 모니터 화면 (50, 620)위치를 클릭하게 한다. 그림판 프로그램이 모니터 화면에 뜨는 위치는 직전에 실행했을때 종료한 위치에서 뜨는것으로 보인다. 실은 저 부분을 좀 더 오류없이 처리하려면 모니터 화면에서 그림판 프로그램의 특정메뉴 아이콘을 캡쳐해둬서 그 위치를 인식하도록 하는 것이 더 좋을 것이다. pyautogui.locateOnScreen() 함수를 쓰면 된다. 여기서는 굳이 여기까지 하진 않겠다.

실행 결과는 아래처럼 움직인다. (영상이 실행안되면 F5로 새로고침 한다.)

Automation_움짤

간단한 동작을 위한 간단한 코드. 알아보고 생각할 건 조금 있었지만 어렵지 않게 구현됬다. pyautogui와 적당한 조건문, 반복문의 조합으로 기상천외한 일들 할 수 있을 것이다.

Summary

GUI 자동화는 일단 직관적이다. 내가 평소에 마우스 키보드 조작하던 것을 하나씩 단계별로 코드작성하면 됬다. 각 동작마다 조금씩 기다리도록 주의하면 된다. 화면이 변하는것을 보면 괜히 뭐 있어보이고 재밌기도 하다.

그런데, 이정도를 자동화 혹은 RPA라고 말하기는 뭔가 애매하다. 자동화가 아닌건 아닌데 좀 더 많은 것을 오류없이 일을 처리하고 싶다.

예를 들면 컴퓨터가 성능이 좀 떨어져서 혹은 인터넷환경처럼 특정 페이지가 로딩되는데 오래걸리거나 프로그램 실행중 오류가 생기는 경우를 생각해보자. 사람이라면 조금 기다리던지 다시 프로그램을 실행할 것이다. 하지만 GUI자동화 방식은 코드 전체가 내 의도와 다르게 작동할 가능성이 매우 높다. 뭔가 컴퓨터와 더 깊은 대화가 필요하다. 다음번에는 COM Object 써보자.

This post is licensed under CC BY 4.0 by the author.