-
카카오톡 봇 만들기 ( python, pc 카톡, 비활성 ) - 2편python/매크로 2020. 4. 24. 06:50반응형
3줄 선 요약
- 플러스친구 아님
- 모바일 어플을 활용한 방법 아님
- pc카톡, python 으로 pc 환경에서 봇을 제작함
2020/04/21 - [python] - 카카오톡 봇 만들기 ( python, pc 카톡, 비활성 ) - 1편
1편 에서는 봇의 기능 설명과, 메시지 전송 및 대략적인 구조에 대해서 다루었고,
이번 글에서는 친구목록 또는 채팅방 목록 중 선택하는 방법을 다루려 합니다.
pc카톡의 클래스 구조
소스 설명을 위해 보긴 해야 하는 pc카톡 구조입니다
최대한 쉽게 필요한 부분만 짚고 넘어갈게요
목적은 빨간색 화살표(←) 부분
친구목록 or 채팅목록 의 검색창(Edit) 에 입력을 하려고 한다
검색창의 접근 과정 순서
친구목록 : 0 → 1 → 2-1 → 3 (이때는 첫 번째 화살표 부분이 3 이 된다.)
채팅목록 : 0 → 1 → 2-2 → 3 (파란 배경색 부분)
여기서 주의할 부분이 있는데
2-1 과 2-2 의 클래스 이름이 빨간색 밑줄로 표시한 'EVA_Window' 로 같다
이 부분은 아래의 코드를 보면서 설명함
채팅방 목록 검색
# # 채팅방 목록 검색하는 Edit 핸들 (채팅방이 열려있지 않아도 전송 가능하기 위하여) hwndkakao = win32gui.FindWindow(None, "카카오톡") hwndkakao_edit1 = win32gui.FindWindowEx( hwndkakao, None, "EVA_ChildWindow", None) hwndkakao_edit2_1 = win32gui.FindWindowEx( hwndkakao_edit1, None, "EVA_Window", None) hwndkakao_edit2_2 = win32gui.FindWindowEx( hwndkakao_edit1, hwndkakao_edit2_1, "EVA_Window", None) hwndkakao_edit3 = win32gui.FindWindowEx( hwndkakao_edit2_2, None, "Edit", None) # # Edit에 검색 _ 입력되어있는 텍스트가 있어도 덮어쓰기됨 win32api.SendMessage(hwndkakao_edit3, win32con.WM_SETTEXT, 0, kakao_opentalk_name) time.sleep(1) # 안정성 위해 필요 SendReturn(hwndkakao_edit3)
위 코드의 기능은 채팅방을 이름으로 검색해서 들어간다
1편에서 FindWindow / FindWindowEx 사용법은 다루었으니 간략하게 설명하면
FindWindow로 캡션(창 이름) 이 '카카오톡' 이라는 최상위 핸들을 가져오고
FindWindowEx 로 자식 핸들을 하나씩 타고 내려가
최종적으로 검색창(Edit) 핸들을 가져온다
이때 순서는 검색창의 접근 과정 순서에 따랐으며
보기 쉽도록 PC카톡 클래스 구조의 좌측 빨간숫자 0, 1, 2-1, 2-2, 3 에 맞춰, 변수명을
hwndkakao_edit1
hwndkakao_edit2_1
hwndkakao_edit2_2
hwndkakao_edit3
이라고 지어놨으니 비교해가면서 보면 된다.
문제
문제가 있는 부분은 2-1 과 2-2 자식 핸들끼리
클래스 이름이 'EVA_Window' 로 중복이 되는 문제인데
FindWindowEx 로 자식 핸들을 탐색할 때
첫 번째 자식부터 순차적으로 조건이 맞을 때까지 돌아간다
2-1 : 친구 목록
2-2 : 채팅방 목록
이 글에서는 2-2 채팅방 목록을 가고 싶은데
2-1 에서 이름이 같아 멈춰버리니 2-2를 갈 수 없게 되어버린다.
해결
올려놓은 코드 중 아래 2-2 코드를 보면
hwndkakao_edit2_2 = win32gui.FindWindowEx( hwndkakao_edit1, hwndkakao_edit2_1, "EVA_Window", None)
빨간색으로 강조한 매개변수가 자식 핸들을 찾는 시작 포인트를 지정하는 부분이다
기존엔 None 값을 줬었으며, 처음부터 찾으란 뜻이다
때문에 2-1(친구목록) 의 핸들을 주고 이 다음부터 검색해라~ 라고 했기 때문에
중복된 이름을 건너뛰고 2-2(채팅방 목록)의 핸들을 가져올 수 있다
만약 채팅방 목록이 아닌 친구목록에서 검색을 하고 싶다면, 아래의 코드를 쓰면 됨
# # 친구목록 검색하는 Edit (채팅방이 열려있지 않아도 전송 가능하기 위하여) hwndkakao = win32gui.FindWindow(None, "카카오톡") hwndkakao_edit1 = win32gui.FindWindowEx( hwndkakao, None, "EVA_ChildWindow", None) hwndkakao_edit2_1 = win32gui.FindWindowEx( hwndkakao_edit1, None, "EVA_Window", None) hwndkakao_edit3 = win32gui.FindWindowEx( hwndkakao_edit2_1, None, "Edit", None) # # Edit에 검색 _ 입력되어있는 텍스트가 있어도 덮어쓰기됨 win32api.SendMessage(hwndkakao_edit3, win32con.WM_SETTEXT, 0, kakao_opentalk_name) time.sleep(1) # 안정성 위해 필요 SendReturn(hwndkakao_edit3)
아래 코드는 1편과 2편의 코드를 모두 합친 것
import time, win32con, win32api, win32gui # # 카톡창 이름, (활성화 상태의 열려있는 창) kakao_opentalk_name = '메모장' # # 채팅방에 메시지 전송 def kakao_sendtext(chatroom_name, text): # # 핸들 _ 채팅방 hwndMain = win32gui.FindWindow( None, chatroom_name) hwndEdit = win32gui.FindWindowEx( hwndMain, None, "RichEdit20W", None) # hwndListControl = win32gui.FindWindowEx( hwndMain, None, "EVA_VH_ListControl_Dblclk", None) win32api.SendMessage(hwndEdit, win32con.WM_SETTEXT, 0, text) SendReturn(hwndEdit) # # 엔터 def SendReturn(hwnd): win32api.PostMessage(hwnd, win32con.WM_KEYDOWN, win32con.VK_RETURN, 0) time.sleep(0.01) win32api.PostMessage(hwnd, win32con.WM_KEYUP, win32con.VK_RETURN, 0) # # 채팅방 열기 def open_chatroom(chatroom_name): # # 채팅방 목록 검색하는 Edit (채팅방이 열려있지 않아도 전송 가능하기 위하여) hwndkakao = win32gui.FindWindow(None, "카카오톡") hwndkakao_edit1 = win32gui.FindWindowEx( hwndkakao, None, "EVA_ChildWindow", None) hwndkakao_edit2_1 = win32gui.FindWindowEx( hwndkakao_edit1, None, "EVA_Window", None) hwndkakao_edit2_2 = win32gui.FindWindowEx( hwndkakao_edit1, hwndkakao_edit2_1, "EVA_Window", None) hwndkakao_edit3 = win32gui.FindWindowEx( hwndkakao_edit2_2, None, "Edit", None) # # Edit에 검색 _ 입력되어있는 텍스트가 있어도 덮어쓰기됨 win32api.SendMessage(hwndkakao_edit3, win32con.WM_SETTEXT, 0, chatroom_name) time.sleep(1) # 안정성 위해 필요 SendReturn(hwndkakao_edit3) time.sleep(1) def main(): open_chatroom(kakao_opentalk_name) # 채팅방 열기 text = "test" kakao_sendtext(kakao_opentalk_name, text) # 메시지 전송 if __name__ == '__main__': main()
사용법은
kakao_opentalk_name = '메모장'
여기에서 '메모장' 부분을 원하는 채팅방 이름으로 바꾸고
나머지는 main 함수에 쓴 것만 가지고 쓰면 됨
1~2편 에서 채팅방을 검색하고 들어가 메시지를 전송하는 것까지 해봤는데
쓰다 보니 생각보다 글이 길어져서 자꾸 자르게 되네요
다음 3편은 1~2편에서 만든 전송 기능을 이용해서
간단하게 크롤링을 한 후 톡방에 알림 톡을 보내는 봇을 만들어보겠습니다.
반응형'python > 매크로' 카테고리의 다른 글
카카오톡 봇 만들기 ( python, pc 카톡, 비활성 ) - 4편 (30) 2020.05.01 카카오톡 봇 만들기 ( python, pc 카톡, 비활성 ) - 3편 (1) 2020.04.27 카카오톡 봇 만들기 ( python, pc 카톡, 비활성 ) - 1편 (30) 2020.04.21