파이썬 캡쳐 매크로 - paisseon kaebchyeo maekeulo

파이썬 캡쳐 매크로 - paisseon kaebchyeo maekeulo


목차

  • pyautogui 매크로 소개
  • 설치 – installation
  • 기본 기능
    • 마우스
    • 키보드
  • 메시지 기능
  • 스크린샷 (screenshot)
  • 윈도우창 활성화


pyautogui 매크로 만들기 사용법 기초를 알아본다. pyautogui는 파이썬 유저들에게 매크로 라이브러리로서 가장 사랑받은 패키지이다. 기본적으로 매크로라는 것은 컴퓨터 작업을 컴퓨터로 하여금 일을 시키는 프로그램을 말한다. 최근에는 오토핫키가 가장 많은 사랑을 받고 있는데, 파이썬 사용자들은 pyautogui 매크로 를 이용하여 경우에 데이터를 처리하고 매크로를 사용하는 법을 한번 알아두면 컴퓨터에서 많은 시간을 보내는 사람들은 업무효율을 극대화할 수 있다.

설치 – installation

기본 기능

기본적으로 매크로라는 것은 모니터 화면에 특정 부위를 읽고 (캡처, 스크린샷) 마우스로 특정 위치를 클릭을 하고 키보드 타이핑을 하는 것을 기본으로 한다. 이 세가지만 기본기능을 먼저 충실히 알아두어야 한다.

pyautogui.size()   # 현재 화면 해상도
pyautogui.position()  # 마우스 현재 위치 (X, Y) 값으로 리턴
pyautogui.onScreen(x, y) #스크린상에 x,y 위치 좌표가 해당하는지 확인. 있으면 True 없으면 False # 이건 보통 쓸모 없음

마우스

pyautogui.moveTo(x, y) # 마우스 커서를 x, y 좌표로 이동 # 이동만 하고 클릭은 하지 않음
pyautogui.dragTo(500, 500, duration=0.5)  # 500, 500 위치로 0.5초에 걸쳐서(커서이동속도) 마우스 커서 이동. 

 pyautogui.click(x=moveToX, y=moveToY, clicks=num_of_clicks, interval=secs_between_clicks, button='left')
# 마우스 클릭. x 값, y값 , 클릭수, 이동속도, 클릭할 버튼('left' 또는 'right' 지정)

pyautogui.rightClick(x=moveToX,  y=moveToY)  #우클릭
pyautogui.middleClick(x=moveToX, y=moveToY)  #스크롤클릭
pyautogui.doubleClick(x=moveToX, y=moveToY)  #더블클릭
pyautogui.tripleClick(x=moveToX, y=moveToY)  #트리플클릭 (3번클릭)

pyautogui.mouseDown(x=moveToX, y=moveToY, button='left')
pyautogui.mouseUp(x=moveToX, y=moveToY, button='left')

키보드

pyautogui.typewrite('Hello world!\n', interval=secs_between_keys) # 키보드 타이핑. interval = 타이핑 속도, 작을수록 빠름

pyautogui.hotkey('ctrl', 'c')  #단축키 누르기
pyautogui.hotkey('ctrl', 'v')  #단축키 누르기

pyautogui.keyDown('backspace') #백스페이스 누르고 있음
pyautogui.keyUp('backspace') # 누르고 있던 백스페이스 해제

메시지 기능

pyautogui.alert('경고창 메세지 적는 곳') # 경고창 띄움. 메세지박스. #확인 버튼만 존재

vars = pyautogui.confirm('확인 또는 취소를 눌러보세요~~~') # 확인 또는 취소 버튼을 누를 수 있는 메시지 박스를 띄움. '확인'을 클릭하면 vars 에 'OK' 리턴, '취소'를 클릭하면 vars 에 'Cancel' 리턴

vars = pyautogui.prompt('문자를 적어보세요~') # 문자열을 적을 수 있는 경고창 띄움
#문자열을 적고 확인을 누르면 문자열이 vars 에 리턴

스크린샷 (screenshot)

pyautogui.screenshot('foo.png') # 전체화면을 캡처하여 foo.png 파일로 저장

temp = pyautogui.locateOnScreen('temp.png') #이미지서치
#현재 화면상에서 temp.png 파일과 일치하는 위치를 찾아서 영역 좌표를 리턴해준다.
# (1420, 854, 300, 200) <-- x, y, x위치로부터 오른쪽으로 300px, y로부터 200px 내려간 만큼의 사각 영역을 의미한다.

centerxy = pyautogui.center(temp) # 위 사각영역에서 한가운데 좌표를 리턴해준다.

pyautogui.click(centerxy) # 한가운데를 클릭한다.

centerxy = pyautogui.locateCenterOnScreen('temp.png') #한번에 이미지와 동일한 화면 위치의 가운데 좌표를 리턴해준다.

이상 pyautogui 매크로 사용법 기초를 알아보았고 보다 자세한 내용은 개별 글 발행하여 링크를 걸어두겠다. 원하는 내용의 글이 있는지는 pyautogui 카테고리를 확인하면 된다.

윈도우창 활성화

pyautogui 패키지를 벗어나지만 매크로를 만들 때 꼭 필요한 부분이라 추가한다. 매크로를 사용하다보면 특정 윈도우창을 활성화시켜야 할 때가 있다. 다음과 같이 하면 된다.

import pygetwindow as gw 
win = gw.getWindowsWithTitle('Chrome')[0] 
#윈도우 타이틀에 Chrome 이 있는 윈도우창 수집하여 리스트로 리턴. 여기서는 [0] 입력하여 첫번째  객체를 지정

win.activate() # 해당 윈도우를 활성화 

# 만약 에러가 자주 발생하면 아래 코드로 실행한다.
if win.isActive == False:
pywinauto.application.Application().connect(handle=win._hWnd).top_window().set_focus()
win.activate()

pyautogui.click(win.center) # 해당 윈도우창의 정가운데 클릭
pyautogui.click(win.left, win.top) # 해당 윈도우창의 가장 왼쪽 위를 클릭

pyautogui.click(win.left+50, win.top+50) # 해당 윈도우창의 가장 왼쪽 위에서 우로 50 밑으로 50 이동한 위치를 클릭

  윈도우에서 파이썬의 pyautogui 를 사용하여 마우스를 제어하여 반복적인 단순 노동을 자동화하기 위한 매크로 프로그램을 만들기 시작했다. 사실 초반에는 애를 좀 먹었다. 아무리 해도 프로그램이 클릭이 되지 않았기 때문인데, 허무하게도 관리자모드로 실행하니 작동하기 시작했다. 정말 허망했다. 안되던게 모두 되기 시작한다. 관리자 모드의 힘은 어디까지인것인지!! 

  그래서 잘 만들고 있는데, 몇가지 문제들이 발생하기 시작했다. 일단 한가지는 예외처리를 해야 하는 상황이다. 나는 A 라는 상황을 진행해야 하는데, 버튼이 비활성된다든지, 버튼의 위치가 바뀐다든지 그러한 이유로 프로그램이 오작동하기 시작한 것이다. 또 다른 문제는, 마우스는 언제나 지정한 곳을 지정한 시간에 클릭한다는 것이다. 그 시간에 내가 원하는 부분이 정확한 위치에 있지 않을 경우 이후는 무조건 오작동의 길로 접어드는 것이다. 그래서 생각해 보았다. 어떻게 하면, 이 오작동을 막을 수 있을까? 

  내가 내린 결론은 이미지를 이용하는 것이었다. 화면을 캡쳐한 후, 특정화면이 나와야 하는데 내가 원하는 화면이 아닐 경우 프로그램을 중단시켜 버리거나, 그 부분은 뛰어 넘고 다른 부분으로 이동하게 하는 것이다. 방식은 간단했다. 

1. 화면을 캡쳐한다. 
2. 캡쳐한 파일에서 비교할 부분을 잘라낸다
3. 기존에 저장한 비교부분 이미지와 동일한지를 체크한다
4. 동일할 때, 동일하지 않을 때 처리를 다르게 한다. 

4번의 경우는 그냥 if ... else 문을 사용하면 되기 때문에 딱히 생각을 오래할 필요는 없었다. 하지만 캡쳐한 이미지를 잘라낼 때 내 속을 좀 썩였다. 이 부분은 소스를 보면서 설명해 드리고자 한다. 

우선 이미지 캡쳐와 저장에 필요한 모듈을 설치해야 한다

pip install pillow

바로 pillow 가 오늘 필요한 모듈이다. 다른 역할은 사실 잘 모른다. 현재로서는 딱히 관심이 없다보니, 일단 무언가를 하면서 익히는 스타일의 나로서는 이 이상의 기능은 당장에 필요가 없기 때문이기도 하다. 

자, 그럼 소스를 작성해보도록 하자

from PIL import ImageGrab, Image

img = ImageGrab.grab()
imgCrop = img.crop((100,100,200,200))
saveas="{}{}".format('imagename','.png')
imgCrop.save(saveas)

img1 = Image.open(saveas)
img2 = Image.open('check.png')

if img1 == img2 :
	print("같다")
else :
	print("다르다")

사실 조금 더 간단하게 만들 수도 있을 것 같지만, 일단은 이렇게 해둔 상태다. 테스트를 해보기 전이기 때문이다. 

  소스를 하나하나 설명하자면.. 첫번째 줄의 "from PIL import ImageGrab, Image" 는 PIL 이라는 모듈("pip install  pillow" 라는 이름으로 설치한 모듈)안에 있는 ImageGrab 이라는 함수와 Image 라는 함수를 가져와서 사용할 것이라는 명령어다.  3번째 줄에 있는 ImageGrab.grab() 이라는 명령어는 "화면전체를 캡쳐하라"는 명령이다. 화면 전체를 캡쳐해서 img 라는 변수에 저장을 하고 4번째 줄에서는 img 라는 변수에 crop을 실행하는데 100, 100, 200, 200 이라는 좌표값을 기준으로 하는 사각형으로 자르라는 말이다. 순서는 x1, y1, x2, y2 이다. 난 처음에 이걸 모르고 처음 x1, y1 을 제대로 작성 한 후 x2, y2 는 이미지의 사이즈를 집어넣어 계속 오류를 발생시켰다. 아마도 ImageGrab.grab() 부분의 괄호() 안에 (100, 100, 200, 200) 을 바로 작성하는 것도 가능할 듯 보인다. 그렇다면 소스 코드가 1줄 줄어드는 것이라 행복한데, 아직 테스트를 안해봤다. 그냥 하면 되지만 게으른 내 성격상 안할지도 모르겠다. 5번째 줄은 파일명을 지정하는 방식인데 {}{} 는 저 안에 두개의 값이 각각 들어갈 수 있다는 것을 말하고, format('a','b') 와 같은 형식으로 집어 넣은 것인데, a 와 b 를 넣으면 출력은 그냥 ab 로 출력된다고 보면 된다. 사실 saveas = 'imagename.png' 라고 작성해도 되고, 바로 아래줄인 6번째 줄에 saveas 대신 'imagename.png' 를 넣어줘도 상관은 없을 듯 싶다. 그리고 6번째 줄에서 나는 캡쳐해서 잘라낸 이미지를 저장을 시켰다. (꼭 저장을 해야만 가능한지 여부는 아직 테스트해보진 않았다)  8번째 줄은 방금 잘라서 저장한 이미지 파일을 불러오는 명령어다. Image.open() 이라는 명령어로 괄호 안에 있는 파일을 열어서 img1 이라는 변수에 대응시켰고, 9번째 줄은 check.png 라는 파일을 불러와서 img2 에 넣은 것이다.  10번째 줄에서는 img1 과 img2 가 '같다' 인지 비교를 해 보았고, 11번째 줄은 같을 때, 12번째 줄 else 는 "그렇지 않다면" 을 의미한다고 보면 된다. 그래서 13번째 줄은 다를 때 print 즉 () 안의 내용을 출력하라는 명령이다. 

  이와 같은 방식의 소스를 사용한다면, 단순 예외처리 뿐만 아니라, 마우스의 위치가 틀어졌을 때에도 대처가 가능할 것으로 본다. 사용한 이미지 파일은 모두 삭제하도록 처리한다면 나중에 더는 사용하지 않는 이미지가 넘쳐나지 않는데 도움이 될 것이라고 본다. 이미지 삭제는 사실상 파일 삭제이므로 파일 삭제기능을 넣어야 하는데.. 기억나지 않으므로 당장은 패스하도록 한다.

다음 번에 이 모듈을 사용한다면, 이번 보다 더 빠르게 사용이 가능하지 않을까 싶다. 
또한 화면캡쳐와 비교를 이용한다면, 오토마우스도 보다 더 정확도를 높일 수 있으리라 생각된다. 많은 업무의 자동화가 가능할 것으로 보인다. 검색하다보니, 이미지에서 글씨를 추출하는 모듈도 있는 것 같던데... 그런 것 까지 사용한다면 점점 더 많은 일을 오토마우스가 할 수 있을 것으로 보인다. 

궁금해진다. 어느 곳의 반복작업을 자동화하면 좋을지 말이다.