| 
 | 
 
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册  
 
x
 
tx在8月初将酷q等一切工具搞掉了, 但是我的砖还得搬, 于是临时写了一个抓取消息的脚本。 
原理是通过IAccessible接口抓取聊天窗口的消息再处理得到每条消息, 不才, 现成资料是用ahk调用dll然后我就直接用了而没有折腾改成Python。 
使用方法: 
三个文件放一起,  
os.system("start QQ抓取.ahk xxx")   xxx改成要监控的窗口名, 多个窗口就复制这行 
destination = ('127.0.0.1', 5888)      用socket把消息发到这个地址 
 
- import os
 
 - import threading
 
 - import socket
 
 - import json
 
 - import re
 
  
 
- def parser(new_text, l_old_text):
 
 -     new_text = re.sub(r"\n {2}(?=.+\(\d+\) ( |202\d-\d\d-\d\d )\d\d:\d\d:\d\d)", '-cut-', new_text.replace('\r', '\n'))  # \r改\n, 在每个用户标识前将'\n  '替换成分隔符号-cut-(不直接split是因为空格开头的消息会出错)
 
 -     l_new_text = new_text.split('-cut-')
 
 -     for text in l_new_text:
 
 -         if text not in l_old_text:
 
 -             QQID = re.search(r"(?<=\()\d+(?=\))", text).group()
 
 -             message = re.search(r"(?<=\d\d:\d\d:\d\d\n ).+", text, re.DOTALL).group()
 
 -             client = socket.socket()
 
 -             try:
 
 -                 client.connect(destination)
 
 -                 client.send(json.dumps({'type': 'message', 'user_id': QQID, 'message': message}).encode('utf8'))
 
 -             except Exception:
 
 -                 print("异常 - 发送失败")
 
 -             client.close()
 
 -     return l_new_text
 
  
 
- def handle_receive(client):
 
 -     receive = client.recv(65536).decode('utf8')
 
 -     if "ahk-" in receive:
 
 -         name = receive
 
 -         l_old_text = []
 
 -         print('已连接:', receive)
 
 -         while True:
 
 -             try:
 
 -                 all_text = client.recv(65536).decode('utf8')
 
 -                 if all_text:
 
 -                     l_old_text = parser(all_text[2:-2], l_old_text)  # 不要前面空格和最后面\r空格
 
 -                 else:
 
 -                     client.close()
 
 -                     print('\n已断开:', name)
 
 -                     break
 
 -             except Exception as e:
 
 -                 print('异常 - 处理消息', name, e)
 
  
 
- if __name__ == '__main__':
 
 -     server = socket.socket()
 
 -     server.bind(('', 5886))
 
 -     server.listen(5)
 
 -     os.system("start QQ抓取.ahk xxx")
 
 -     destination = ('127.0.0.1', 5888)
 
  
-     while True:
 
 -         try:
 
 -             client = server.accept()[0]
 
 -             thread = threading.Thread(target=handle_receive, args=(client, ))
 
 -             thread.start()
 
 -         except Exception as e:
 
 -             print('异常 - 主循环', e)
 
 
  复制代码 
 
 
 
QQ抓取.ahk: 
- #Persistent
 
 - #SingleInstance,force
 
 - #Include Socket.ahk
 
 - SetBatchLines,-1
 
  
- Acc_Init()
 
 - {
 
 -         static h
 
 -         If Not h
 
 -                 h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
 
 - }
 
 - Acc_ObjectFromWindow(hWnd, idObject = 0)
 
 - {
 
 -         Acc_Init()
 
 -         If DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", hWnd, "UInt", idObject&=0xFFFFFFFF, "Ptr", -VarSetCapacity(IID,16)+NumPut(idObject==0xFFFFFFF0?0x46000000000000C0:0x719B3800AA000C81,NumPut(idObject==0xFFFFFFF0?0x0000000000020400:0x11CF3C3D618736E0,IID,"Int64"),"Int64"), "Ptr*", pacc)=0
 
 -         Return ComObjEnwrap(9,pacc,1)
 
 - }
 
 - Acc_Query(Acc) {
 
 -         Try Return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
 
 - }
 
 - Acc_Children(Acc) {
 
 -         If ComObjType(Acc,"Name") != "IAccessible"
 
 -                 ErrorLevel := "Invalid IAccessible Object"
 
 -         Else {
 
 -                 Acc_Init(), cChildren:=Acc.accChildCount, Children:=[]
 
 -                 If DllCall("oleacc\AccessibleChildren", "Ptr",ComObjValue(Acc), "Int",0, "Int",cChildren, "Ptr",VarSetCapacity(varChildren,cChildren*(8+2*A_PtrSize),0)*0+&varChildren, "Int*",cChildren)=0 {
 
 -                         Loop %cChildren%
 
 -                                 i:=(A_Index-1)*(A_PtrSize*2+8)+8, child:=NumGet(varChildren,i), Children.Insert(NumGet(varChildren,i-8)=9?Acc_Query(child):child), NumGet(varChildren,i-8)=9?ObjRelease(child):
 
 -                         Return Children.MaxIndex()?Children:
 
 -                 } Else
 
 -                         ErrorLevel := "AccessibleChildren DllCall Failed"
 
 -         }
 
 - }
 
 - GetElementByName(AccObj, name) {
 
 -    if (AccObj.accName(0) = name)
 
 -       return AccObj
 
 -    
 
 -    for k, v in Acc_Children(AccObj)
 
 -       if IsObject(obj := GetElementByName(v, name))
 
 -          return obj
 
 - }
 
  
 
- title = %1%  ; start QQ抓取.ahk c
 
  
- client := new SocketTCP()
 
 - client.connect("127.0.0.1",5886)
 
 - client.sendText("ahk-" title)
 
  
- hwnd := WinExist(title)
 
 - window := Acc_ObjectFromWindow(hwnd)
 
 - widget := GetElementByName(window, "消息")
 
  
- old_text := widget.accValue(0)
 
  
- Loop, {
 
 -     sleep, 100
 
 -     current_text := widget.accValue(0)
 
 -     if (current_text != old_text){
 
 -         client.sendText(current_text)
 
 -         old_text := current_text
 
 -     }
 
 - }
 
 
  复制代码 
 
 
Socket.ahk: 
- ;~ https://autohotkey.com/board/topic/94376-socket-class-%c3%bcberarbeitet/
 
 - class Socket
 
 - {
 
 -   static __eventMsg := 0x9987
 
 -   
 
 -   __New(s=-1)
 
 -   {
 
 -     static init
 
 -     if (!init)
 
 -     {
 
 -       DllCall("LoadLibrary", "str", "ws2_32", "ptr")
 
 -       VarSetCapacity(wsadata, 394+A_PtrSize)
 
 -       DllCall("ws2_32\WSAStartup", "ushort", 0x0000, "ptr", &wsadata)
 
 -       DllCall("ws2_32\WSAStartup", "ushort", NumGet(wsadata, 2, "ushort"), "ptr", &wsadata)
 
 -       OnMessage(Socket.__eventMsg, "SocketEventProc")
 
 -       init := 1
 
 -     }
 
 -     this.socket := s
 
 -   }
 
 -   __Delete()
 
 -   {
 
 -     this.disconnect()
 
 -   }
 
 -   __Get(k, v)
 
 -   {
 
 -     if (k="size")
 
 -       return this.msgSize()
 
 -   }
 
 -   connect(host, port)
 
 -   {
 
 -     if ((this.socket!=-1) || (!(faddr := next := this.__getAddrInfo(host, port))))
 
 -       return 0
 
 -     while (next)
 
 -     {
 
 -       sockaddrlen := NumGet(next+0, 16, "uint")
 
 -       sockaddr := NumGet(next+0, 16+(2*A_PtrSize), "ptr")
 
 -       if ((this.socket := DllCall("ws2_32\socket", "int", NumGet(next+0, 4, "int"), "int", this.__socketType, "int", this.__protocolId, "ptr"))!=-1)
 
 -       {
 
 -         if ((r := DllCall("ws2_32\WSAConnect", "ptr", this.socket, "ptr", sockaddr, "uint", sockaddrlen, "ptr", 0, "ptr", 0, "ptr", 0, "ptr", 0, "int"))=0)
 
 -         {
 
 -           DllCall("ws2_32\freeaddrinfo", "ptr", faddr)
 
 -           return Socket.__eventProcRegister(this, 0x21)
 
 -         }
 
 -         this.disconnect()
 
 -       }
 
 -       next := NumGet(next+0, 16+(3*A_PtrSize), "ptr")
 
 -     }
 
 -     this.lastError := DllCall("ws2_32\WSAGetLastError")
 
 -     return 0
 
 -   }
 
 -   bind(host, port)
 
 -   {
 
 -     if ((this.socket!=-1) || (!(faddr := next := this.__getAddrInfo(host, port))))
 
 -       return 0
 
 -     while (next)
 
 -     {
 
 -       sockaddrlen := NumGet(next+0, 16, "uint")
 
 -       sockaddr := NumGet(next+0, 16+(2*A_PtrSize), "ptr")
 
 -       if ((this.socket := DllCall("ws2_32\socket", "int", NumGet(next+0, 4, "int"), "int", this.__socketType, "int", this.__protocolId, "ptr"))!=-1)
 
 -       {
 
 -         if (DllCall("ws2_32\bind", "ptr", this.socket, "ptr", sockaddr, "uint", sockaddrlen, "int")=0)
 
 -         {
 
 -           DllCall("ws2_32\freeaddrinfo", "ptr", faddr)
 
 -           return Socket.__eventProcRegister(this, 0x29)
 
 -         }
 
 -         this.disconnect()
 
 -       }
 
 -       next := NumGet(next+0, 16+(3*A_PtrSize), "ptr")
 
 -     }
 
 -     this.lastError := DllCall("ws2_32\WSAGetLastError")
 
 -     return 0
 
 -   }
 
 -   listen(backlog=32)
 
 -   {
 
 -     return (DllCall("ws2_32\listen", "ptr", this.socket, "int", backlog)=0) ? 1 : 0
 
 -   }
 
 -   accept()
 
 -   {
 
 -     if ((s := DllCall("ws2_32\accept", "ptr", this.socket, "ptr", 0, "int", 0, "ptr"))!=-1)
 
 -     {
 
 -       newsock := new Socket(s)
 
 -       newsock.__protocolId := this.__protocolId
 
 -       newsock.__socketType := this.__socketType
 
 -       Socket.__eventProcRegister(newsock, 0x21)
 
 -       return newsock
 
 -     }
 
 -     return 0
 
 -   }
 
 -   disconnect()
 
 -   {
 
 -     Socket.__eventProcUnregister(this)
 
 -     DllCall("ws2_32\closesocket", "ptr", this.socket, "int")
 
 -     this.socket := -1
 
 -     return 1
 
 -   }
 
 -   msgSize()
 
 -   {
 
 -     VarSetCapacity(argp, 4, 0)
 
 -     if (DllCall("ws2_32\ioctlsocket", "ptr", this.socket, "uint", 0x4004667F, "ptr", &argp)!=0)
 
 -       return 0
 
 -     return NumGet(argp, 0, "int")
 
 -   }
 
 -   send(addr, length)
 
 -   {
 
 -     if ((r := DllCall("ws2_32\send", "ptr", this.socket, "ptr", addr, "int", length, "int", 0, "int"))<=0)
 
 -       return 0
 
 -     return r
 
 -   }
 
 -   sendText(msg, encoding="UTF-8")
 
 -   {
 
 -     VarSetCapacity(buffer, length := (StrPut(msg, encoding)*(((encoding="utf-16")||(encoding="cp1200")) ? 2 : 1))-1)
 
 -     StrPut(msg, &buffer, encoding)
 
 -     return this.send(&buffer, length)
 
 -   }
 
 -   recv(byref buffer, wait=1)
 
 -   {
 
 -     while ((wait) && ((length := this.msgSize())=0))
 
 -       sleep, 100
 
 -     if (length)
 
 -     {
 
 -       VarSetCapacity(buffer, length)
 
 -       if ((r := DllCall("ws2_32\recv", "ptr", this.socket, "ptr", &buffer, "int", length, "int", 0))<=0)
 
 -         return 0
 
 -       return r
 
 -     }
 
 -     return 0
 
 -   }
 
 -   recvText(wait=1, encoding="UTF-8")
 
 -   {
 
 -     if (length := this.recv(buffer, wait))
 
 -       return StrGet(&buffer, length, encoding)
 
 -     return
 
 -   }
 
 -   __getAddrInfo(host, port)
 
 -   {
 
 -     a := ["127.0.0.1", "0.0.0.0", "255.255.255.255", "::1", "::", "FF00::"]
 
 -     conv := {localhost:a[1], addr_loopback:a[1], inaddr_loopback:a[1], addr_any:a[2], inaddr_any:a[2], addr_broadcast:a[3]
 
 -     , inaddr_broadcast:a[3], addr_none:a[3], inaddr_none:a[3], localhost6:a[4], addr_loopback6:a[4], inaddr_loopback6:a[4]
 
 -     , addr_any6:a[5], inaddr_any:a[5], addr_broadcast6:a[6], inaddr_broadcast6:a[6], addr_none6:a[6], inaddr_none6:a[6]}
 
 -     if (conv[host])
 
 -       host := conv[host]
 
 -     VarSetCapacity(hints, 16+(4*A_PtrSize), 0)
 
 -     NumPut(this.__socketType, hints, 8, "int")
 
 -     NumPut(this.__protocolId, hints, 12, "int")
 
 -     if ((r := DllCall("ws2_32\getaddrinfo", "astr", host, "astr", port, "ptr", &hints, "ptr*", next))!=0)
 
 -     {
 
 -       this.lastError := DllCall("ws2_32\WSAGetLastError")
 
 -       return 0
 
 -     }
 
 -     return next
 
 -   }
 
 -   __eventProcRegister(obj, msg)
 
 -   {
 
 -     a := SocketEventProc(0, 0, "register", 0)
 
 -     a[obj.socket] := obj
 
 -     return (DllCall("ws2_32\WSAAsyncSelect", "ptr", obj.socket, "ptr", A_ScriptHwnd, "uint", Socket.__eventMsg, "uint", msg)=0) ? 1 : 0
 
 -   }
 
 -   __eventProcUnregister(obj)
 
 -   {
 
 -     a := SocketEventProc(0, 0, "register", 0)
 
 -     a.remove(obj.socket)
 
 -     return (DllCall("ws2_32\WSAAsyncSelect", "ptr", obj.socket, "ptr", A_ScriptHwnd, "uint", 0, "uint", 0)=0) ? 1 : 0
 
 -   }
 
 - }
 
 - SocketEventProc(wParam, lParam, msg, hwnd)
 
 - {
 
 -   global Socket
 
 -   static a := []
 
 -   Critical
 
 -   if (msg="register")
 
 -     return a
 
 -   if (msg=Socket.__eventMsg)
 
 -   {
 
 -     if (!isobject(a[wParam]))
 
 -       return 0
 
 -     if ((lParam & 0xFFFF) = 1)
 
 -       return a[wParam].onRecv(a[wParam])
 
 -     else if ((lParam & 0xFFFF) = 8)
 
 -       return a[wParam].onAccept(a[wParam])
 
 -     else if ((lParam & 0xFFFF) = 32)
 
 -     {
 
 -       a[wParam].socket := -1
 
 -       return a[wParam].onDisconnect(a[wParam])
 
 -     }
 
 -     return 0
 
 -   }
 
 -   return 0
 
 - }
 
 -  
 
 - class SocketTCP extends Socket
 
 - {
 
 -   static __protocolId := 6 ;IPPROTO_TCP
 
 -   static __socketType := 1 ;SOCK_STREAM
 
 - }
 
 -  
 
 - class SocketUDP extends Socket
 
 - {
 
 -   static __protocolId := 17 ;IPPROTO_UDP
 
 -   static __socketType := 2 ;SOCK_DGRAM
 
 -  
 
 -   enableBroadcast()
 
 -   {
 
 -     VarSetCapacity(optval, 4, 0)
 
 -     NumPut(1, optval, 0, "uint")
 
 -     if (DllCall("ws2_32\setsockopt", "ptr", this.socket, "int", 0xFFFF, "int", 0x0020, "ptr", &optval, "int", 4)=0)
 
 -       return 1
 
 -     return 0
 
 -   }
 
 -   disableBroadcast()
 
 -   {
 
 -     VarSetCapacity(optval, 4, 0)
 
 -     if (DllCall("ws2_32\setsockopt", "ptr", this.socket, "int", 0xFFFF, "int", 0x0020, "ptr", &optval, "int", 4)=0)
 
 -       return 1
 
 -     return 0
 
 -   }
 
 - }
 
  复制代码 |   
 
 
 
 |