使用pywin32制作qq刷屏軟件
思路:
- 使用pywin32,來訪問windows系統的剪貼板,把要發送的內容加入剪貼板中
- 使用pywin32,模仿按鍵操作“control+v”把內容復制到QQ的聊天窗口上,然后“enter”發送消息。
- 文件讀取,把要刷屏的語言保存在本地的shuaping.txt中,一次性讀取到列表中。然后一條一條的發送完成刷屏。
參考:
如何用python模擬鍵盤輸入
python訪問剪貼板
代碼:
- python操作剪貼板:如何把文件內容復制進入剪貼板
#-*- coding: utf-8 -*-
import win32clipboard as cb
import win32con
date = "Hello,World"
cb.OpenClipboard()#打開剪貼板
cb.SetClipboardData(win32con.CF_TEXT, date)#把數劇復制到剪貼板
cb.CloseClipboard()#用完后關閉剪貼板
試一試粘貼,看內容是否變成了“Hello World”
- 模仿按鍵操作“control+v”和“enter”
import win32clipboard as cb
import win32con
import win32api
date = "Hello,World"
cb.OpenClipboard()#打開剪貼板
cb.SetClipboardData(win32con.CF_TEXT, date)#把數劇復制到剪貼板
cb.CloseClipboard()#用完后關閉剪貼板
win32api.keybd_event(17,0,0,0) #ctrl鍵位碼是17
win32api.keybd_event(86,0,0,0) #v鍵位碼是86
win32api.keybd_event(86,0,win32con.KEYEVENTF_KEYUP,0) #釋放按鍵
win32api.keybd_event(17,0,win32con.KEYEVENTF_KEYUP,0)
這里發現了一些問題,如果有數據中包含中文字符,粘貼出來是亂碼,搜索后發現復制是默認使用的是ANCI,那么解決方法是指定使用unicode格式
cb.SetClipboardData(win32con.CF_UNICODETEXT, date)就是把這個函數的第一個參數改為CF_UNICODETEXT
- 讀取文件
def open_file(filename):
f = open(filename, "r")
content = f.readlines() #考慮到這個文件內容一般不會很大,就一次性讀取到列表了。
f.close()
return content
- 使用wxpython 編寫圖像界面:
import wx
class Screen(wx.Frame):
def __init__(self):
self.explain = u' 使用說明'
wx.Frame.__init__(self, parent=None, id=1, title=u"QQ刷屏器", size=(600,400))
self.panel = wx.Panel(self, -1)
self.Centre() #居中顯示窗口
self.dateText = wx.TextCtrl(self.panel, -1, self.explain, style=wx.TE_MULTILINE, size=(300,330), pos=(1, 10))
version = wx.StaticText(self.panel, -1, u"版本1.0\n作者:即刻", pos=(520,320))
self.open_file = wx.Button(self.panel, label=u'打開刷屏文件 ', pos=(310,40))
self.start = wx.Button(self.panel, label=u'開始刷屏', pos=(450,40))
self.SleepTxet = wx.StaticText(self.panel, -1, u"刷屏的時間間隔(s):", pos=(310,10))
self.Sleep = wx.TextCtrl(self.panel, -1, "0.5", pos=(450,10))
self.SaveDate = wx.Button(self.panel, -1, u"保存對刷屏文件的修改", pos=(310,70))
self.stop = wx.Button(self.panel, -1,label=u"停止刷屏", pos=(450,70))
if __name__ == "__main__":
app = wx.App()
screen = Screen()
screen.Show()
app.MainLoop()
- 完整代碼(整體功能已完成,基本可以使用,但缺陷太坑,根本停不下來!QaQ)
# -*- coding: utf-8 -*-
import win32clipboard as cb
import win32con
import win32api
import time
import os
import wx
class Screen(wx.Frame):
def __init__(self):
self.interval = 2 #默認刷屏的間隔時間
self.condition = False #刷屏的狀態,默認關閉
self.explain = u' 使用說明\n1.你可以在本框內自定義刷屏文本,或者打開刷屏的txt文件\n2.點擊開始后 3s開始刷屏,請立即點擊qq聊天窗口\n3.停止按鈕無效,暫時沒有解決方法 QaQ '
wx.Frame.__init__(self, parent=None, id=1, title=u"QQ刷屏器", size=(600,400))
self.panel = wx.Panel(self, -1)
self.Centre() #居中顯示窗口
self.dateText = wx.TextCtrl(self.panel, -1, self.explain, style=wx.TE_MULTILINE, size=(300,330), pos=(1, 10))
wx.StaticText(self.panel, -1, u"版本1.0\n作者:即刻", pos=(520,320))
open_file = wx.Button(self.panel, label=u'打開刷屏文件 ', pos=(310,40))
start = wx.Button(self.panel, label=u'開始刷屏', pos=(450,40))
wx.StaticText(self.panel, -1, u"刷屏的時間間隔(s):", pos=(310,10))
self.Sleep = wx.TextCtrl(self.panel, -1, str(self.interval), pos=(450,10))
SaveDate = wx.Button(self.panel, -1, u"保存對刷屏文件的修改", pos=(310,70))
stop = wx.Button(self.panel, -1,label=u"停止刷屏", pos=(450,70))
self.Bind(wx.EVT_BUTTON, self.open_file, open_file)
self.Bind(wx.EVT_BUTTON, self.start, start)
self.Bind(wx.EVT_BUTTON, self.stop, stop)
self.Bind(wx.EVT_BUTTON, self.SaveDate, SaveDate)
def stop(self,event):
self.condition = False
def open_file(self, event):
"""open a file"""
self.dirname = ''
dlg = wx.FileDialog(self, "Choose a file", self.dirname, "", "*.*", wx.OPEN) # 調用一個函數打開對話框
if dlg.ShowModal() == wx.ID_OK:
self.filename = dlg.GetFilename()
self.dirname = dlg.GetDirectory()
self.address = os.path.join(self.dirname, self.filename)
f = open(self.address, "r")
file = (f.read()).decode(encoding='utf-8') # 解碼,使文件可以讀取中文
f.close()
self.dateText.Clear()
self.dateText.AppendText(file) # 把打開的文件內容顯示在多行文本框內
dlg.Destroy()
def SaveDate(self, event):
date = (self.dateText.GetValue()).encode(encoding="utf-8") # 編碼,使中文可以正確存儲
f = open(self.address, 'w')
f.write(date)
f.close() # 把文本框內的數據寫入並關閉文件
dlg = wx.MessageDialog(self, u"文件已經成功保存", u"消息提示", wx.OK)
dlg.ShowModal()
dlg.Destroy()
def start(self,event):
self.interval = float(self.Sleep.GetValue()) #因為sleep函數的參數必須為小數,而GetValue()如果數字不帶小數點會得到整數。
file = (self.dateText.GetValue())
date = file.split("\n")
time.sleep(3)
self.condition =True
while self.condition:
for dateline in date:
time.sleep(self.interval)
cb.OpenClipboard() # 打開剪貼板
cb.SetClipboardData(win32con.CF_UNICODETEXT, dateline) # 把數劇復制到剪貼板
cb.CloseClipboard() # 用完后關閉剪貼板
win32api.keybd_event(17, 0, 0, 0) # ctrl鍵位碼是17
win32api.keybd_event(86, 0, 0, 0) # v鍵位碼是86
win32api.keybd_event(86, 0, win32con.KEYEVENTF_KEYUP, 0) # 釋放按鍵
win32api.keybd_event(17, 0, win32con.KEYEVENTF_KEYUP, 0)
win32api.keybd_event(13, 0, 0, 0) # 回車鍵碼是13
win32api.keybd_event(13, 0, win32con.KEYEVENTF_KEYUP, 0) # 釋放回車鍵
if __name__ == "__main__":
app = wx.App()
screen = Screen()
screen.Show()
app.MainLoop()
ps在這幾天查找到了直接給窗口發送消息的辦法,即取得窗口的句柄,利用win32api直接發送消息給窗口,這樣省卻很多中間環節,不過需要了解的知識很多,暫時無精力看它了。
- 如何獲得窗口的句柄:使用spy++或者使用win32的FindWindow和FindWindEx函數
import win32gui
label = u"風的 Android手機" #這里是窗口的名字
hld = win32gui.FindWindow(None,label)
print "%x" % hld #注意此處應該以十六進制輸入,因為python默認十進制輸出。
獲取窗口的句柄:70622 這和我用spy++獲取到的一樣。
這里再次遇到問題:qq的聊天窗口 查找不到子窗口,於是也沒有查找到Edit控件,於是無法把內容傳遞到輸入框內
·搜查資料后得知qq使用的是DirectUI控件和父窗口在一起,無法抓取到控件。
待續。。。
可以完善的地方:
- 使用wxpython來完善使用界面,然后方便的使用cx_freeze或py2exe打包為exe分享給朋友使用
- 使用wxpython的多行文本框來顯示刷屏的語句,並且可以修改,並保存這些語句。
- 可以自己設置發送的間隔時間,設置一次性發送語句的條數。
- 檢測刷屏語句的字數,如果字數超過qq聊天窗口的限制,把一條語句拆分發送。
- 加入圖片刷屏的功能。
這是我想到的最簡單實現qq聊天刷屏的方法,但缺點很明顯,消息刷屏的時候就不能做其他操作了。
問題:
1.是否有其他不用模擬按鍵的方法來發送qq消息。
如果有建議希望您可以詳細告訴我,不勝感激。如果有問題,請評論,我會盡心解答。