본문 바로가기
Algorithm Trading/ComDon 프로그램 개발이야기

8. pyautogui

by 컴돈AI 2024. 1. 27.

목차

pyautogui의 필요성

  • 여러개의 종목을 백테스팅을 진행하다 보면은 일일이 종목마다 하나하나 pinescript 코드를 실행해야 하는 번거로움이 존재합니다. 
  • 이처럼 마우스나 키보드로 단순하게 하던 작업을 pyautogui를 이용하면 직접 클릭이나 키보드 입력을 하지 않아도 자동으로 처리되게 할 수 있습니다.

기본 코드

  • 확실한 제어를 위해서 코드를 실행할때 관리자 권한으로 실행하는 것이 좋습니다.
  • 마우스 클릭
    • 마우스 클릭을 위해서는 해당 마우스 포인터 위치를 알아야합니다. 다음 코드를 통해 마우스 포인터 위치를 파악할 수 있습니다. (클릭하고 싶은 위치로 마우스 포인터를 먼저 이동시켜주어야 합니다.)
      • import pyautogui
        
        current_position = pyautogui.position()
        print(f"현재 마우스 위치는: {current_position}")
      • 실행 결과 x값과 y 값을 기억해 둡니다.
    • 위에서 알아낸 x값과 y값을 이용하여 해당 위치에서 마우스 클릭을 할 수 있습니다.
      • pyautogui.click(x=1998, y=1065)
         
    •  참고 : https://pyautogui.readthedocs.io/en/latest/mouse.html
  • 키보드 입력
    • 키보드 입력은 다음 코드로 가능합니다.
      • # 입력하고 싶은 텍스트
        text_to_type = "hi"
        
        # 텍스트를 타이핑합니다. 기본적으로 각 키 사이에는 0.1초의 간격이 있습니다.
        pyautogui.write(text_to_type, interval=0.1)
         
    • 단, pyautogui는 한글이 입력이 되지 않습니다. 이 문제는 pyperclip 라이브러리를 통해 클립보드로 한글 텍스트를 복사한 다음에 "ctrl + v" (붙여넣기)를 통해 해결할 수 있습니다.
      • import pyautogui
        import pyperclip
        
        # 한글 텍스트를 클립보드에 복사
        text_to_type = "안녕하세요."
        pyperclip.copy(text_to_type)
        
        # 클립보드에서 텍스트 붙여넣기
        pyautogui.hotkey("ctrl", "v")
         
  • 키 사용하기(press(), keyDown(), keyUp(), hotkey())
    • press()는 keyDown()과 keyUp() 함수를 같이 사용한 것입니다.
      • pyautogui.press('shift') # shift 키를 누릅니다.
        pyautogui.press('ctrl') # ctrl 키를 누릅니다.
    • keyDown()은 키를 누른 채로 있는 것이고, keyUp()은 누른 키를 떼는 것입니다.
      • pyautogui.keyDown('ctrl') # ctrl 키를 누른 상태를 유지합니다.
        pyautogui.press('c') # c key를 입력합니다. 
        pyautogui.keyUp('ctrl') # ctrl 키를 뗍니다.
    • 다음과 같은 옵션을 사용할 수 있습니다.
      • pyautogui.press(['left', 'left', 'left']) # 왼쪽 방향키를 세번 입력합니다.
        pyautogui.press('left', presses=3) # 왼쪽 방향키를 세번 입력합니다. 
        pyautogui.press('enter', presses=3, interval=3) # enter 키를 3초에 한번씩 세번 입력합니다.
    • hotkey()는 여러 키를 동시에 입력해야 할 때 사용합니다. (위 설명에서 한글 입력 시에 붙여 넣기를 할 때 pyautogui.hotkey("ctrl", "v")를 사용하였습니다.
      • pyautogui.hotkey('ctrl', 'c') # ctrl + c 키를 입력합니다.
  •  참고 : https://pyautogui.readthedocs.io/en/latest/keyboard.html

예시

pyautogui를 이용한 메모장 작성

  • 간단한 예시로 메모장을 킨 뒤에 특정값을 입력하고 저장하는 작업을 pyautogui를 이용하여 해 보도록 하겠습니다.
  • 전체적인 마우스 키보드 작업 과정
    • 왼쪽 아래 찾기를 클릭한 뒤 메모장을 검색하고 실행합니다.
    • 그 후 메모장에 입력하고 싶은 내용을 입력하고 저장하도록 하겠습니다.
  • pyautogui 이용
    • 필요한 마우스 포인터 위치를 우선 먼저 찾아줍니다.
      • 찾기 / 메모장 x 버튼 / 저장 1 / 저장 2
    • 과정
      • 찾기
      • 메모장입력
      • 엔터
      • 메모장내용입력
      • 메모장 x 버튼
      • 저장 클릭
      • 파일명입력
      • 저장클릭
    • 코드
      • import pyautogui
        import pyperclip
        import time
        
        # 찾기 클릭
        pyautogui.click(x=1991, y=1054)
        time.sleep(0.1)
        
        # 메모장 검색
        text_to_type = "메모장"
        pyperclip.copy(text_to_type)
        pyautogui.hotkey("ctrl", "v")
        time.sleep(1)
        
        # 엔터
        pyautogui.press("enter")
        time.sleep(0.1)
        
        # 메모장 내용입력
        text_to_type = "안녕하세요."
        pyperclip.copy(text_to_type)
        pyautogui.hotkey("ctrl", "v")
        time.sleep(0.1)
        
        # 메모장 x 클릭
        pyautogui.click(x=2430, y=540)
        time.sleep(0.1)
        
        # 저장1 클릭
        pyautogui.click(x=2795, y=530)
        time.sleep(0.1)
        
        # 메모장 제목입력
        text_to_type = "pyautogui메모작성"
        pyperclip.copy(text_to_type)
        pyautogui.hotkey("ctrl", "v")
        time.sleep(0.1)
        
        # 저장2 클릭
        pyautogui.click(x=2744, y=1000)

이베스트투자증권 당일성과검증

  • 조건검색을 이용해서 분단위로 성과 검증을 하려면 아래 작업을 수작업으로 일일이 확인해주어야합니다. (9시 1분, 2분, 3분, ... 이런식으로 쭈욱 클릭해줘야합니다.)
  • 위 작업을 pyautogui를 통해 자동화 해보도록하겠습니다.
    • 과정
      • 시간 클릭후 성과검증하기 클릭
        • 검색결과가 없을 경우 다음과 같은 창이 뜹니다. 엔터키를 통해 해결해줄 수 있습니다.
      • 검색된 종목들을 알캡쳐를 통해 스크린샷 찍기(ctrl+shift+c)
      • 노션 페이지에 해당 시간을 입력한다음에 검색된 종목 스크린샷을 붙여넣기합니다.
      • 위 과정을 검증하고 싶은 시간에 대해서 반복합니다.
    • 예시 코드
      • import pyautogui
        import time
        
        
        def autosave():
            # 먼저 스크린샷 찍기
            ## 이베스트 창 클릭
            pyautogui.click(x=633, y=16)
            time.sleep(0.1)
        
            ## 아래화살표 클릭
            pyautogui.click(x=234, y=240)
            time.sleep(0.1)
        
            ## 시간선택
            pyautogui.click(x=hour_click_point[h][0], y=hour_click_point[h][1])
            time.sleep(0.1)
        
            ## 분선택
            pyautogui.click(x=minute_click_point[m][0], y=minute_click_point[m][1])
            time.sleep(0.1)
        
            ## 성과검증클릭
            pyautogui.click(x=338, y=291)
            time.sleep(2)  # 시간이 좀걸리므로 2초쉬기
        
            ## 검색결과없는경우 엔터 클릭해줘야함. (있어도 엔터해도 아무 지장없음)
            pyautogui.press("enter")
            time.sleep(0.1)
        
            ## 스크린샷
            pyautogui.hotkey("ctrl", "shift", "c")
            time.sleep(0.5)
        
            ## 왼쪽위
            pyautogui.moveTo(x=16, y=376)
        
            ## 오른쪽아래
            pyautogui.dragTo(x=661, y=664, duration=0.7, button="left")
            time.sleep(0.5)
        
            # 노션에 붙여넣기
            ## 노션창 클릭
            pyautogui.click(x=1757, y=27)
            time.sleep(0.5)
        
            ## 시간 입력
            text = "### " + str_h + ":" + str_m
            pyautogui.write(text, interval=0.1)
        
            ## 붙여넣기
            pyautogui.hotkey("ctrl", "v")
            time.sleep(0.5)
        
            # 클릭
            pyautogui.click(x=1279, y=1026)
            time.sleep(0.1)
        
            # 엔터
            pyautogui.press("enter")
            time.sleep(0.1)
        
            # 스크롤
            pyautogui.scroll(-5000)
            time.sleep(0.1)
        
            # 클릭
            pyautogui.click(x=1279, y=1026)
            time.sleep(0.1)
        
        
        hour_click_point = {9 + i: (220 + (18 * i), 260) for i in range(7)}
        
        minute_click_point = {}
        y = 288 - 16
        for i in range(60):
            if i % 10 == 0:
                x = 220
                y += 16
            else:
                x += 18
            minute_click_point[i] = (x, y)
        
        
        for h in [9, 10, 11, 12, 13, 14, 15]:
            if len(str(h)) < 2:
                str_h = "0" + str(h)
            else:
                str_h = str(h)
        
            if h != 15:
                for m in [i for i in range(60)]:
                    if len(str(m)) < 2:
                        str_m = "0" + str(m)
                    else:
                        str_m = str(m)
        
                    autosave()
        
            else:
                for m in [i for i in range(31)]:
                    if len(str(m)) < 2:
                        str_m = "0" + str(m)
                    else:
                        str_m = str(m)
                    autosave()