国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

python使用win32*模塊模擬人工操作——城通網(wǎng)盤下載器(一)

2019-11-08 19:45:01
字體:
供稿:網(wǎng)友
上篇講了,如何使用“城通網(wǎng)盤批量下載器 v2.0”來下載城通網(wǎng)盤的文件。其主要操作集中在主界面中,所以我們首先使用python來模擬在主界面的操作。打開城通網(wǎng)盤批量下載器,進入主界面,如圖所示:然后打開spy++,查看該程序的窗口信息。可以看到,這個程序主窗口的句柄為 00090816(十六進制數(shù)),值得注意的是,這個句柄是每次打開程序時,windows隨機生成的。故不能直接指定句柄號來操作窗口。在python中可以使用win32*模塊來調(diào)用windows函數(shù),之前你得安裝pywin32。使用win32gui.FindWindow和win32gui.FindWindowEx函數(shù)來拿到句柄。具體用法為:FindWindow(lpClassName=None, lpWindowName=None):描述:自頂層窗口(也就是桌面)開始搜索條件匹配的窗體,并返回這個窗體的句柄。不搜索子窗口、不區(qū)分大小寫。找不到就返回0參數(shù):lpClassName:字符型,是窗體的類名,這個可以在Spy++里找到。lpWindowName:字符型,是窗口名,也就是標(biāo)題欄上你能看見的那個標(biāo)題。說明:這個函數(shù)我們僅能用來找主窗口。FindWindowEx(hwndParent=0, hwndChildAfter=0, lpszClass=None, lpszWindow=None);描述:搜索類名和窗體名匹配的窗體,并返回這個窗體的句柄。不區(qū)分大小寫,找不到就返回0。參數(shù):hwndParent:若不為0,則搜索句柄為hwndParent窗體的子窗體。hwndChildAfter:若不為0,則按照z-index的順序從hwndChildAfter向后開始搜索子窗體,否則從第一個子窗體開始搜索。lpClassName:字符型,是窗體的類名,這個可以在Spy++里找到。lpWindowName:字符型,是窗口名,也就是標(biāo)題欄上你能看見的那個標(biāo)題。說明:找到了主窗口以后就靠它來定位子窗體啦。來源: http://blog.csdn.net/seele52/article/details/17504925

對于一個窗口下的多個子窗口,可以通過類名和窗口名進行區(qū)分,若有多個子窗口的類名和窗口名相同,則只能從第一個開始迭代查找。當(dāng)然,如果我們知道子窗口的排列順序,可以對FindWindowEx函數(shù)進行簡單的封裝,通過索引號查找指定窗口的句柄。

1234567891011def find_idxSubHandle(pHandle, winClass, winName = None, index=0):     """    已知子窗口的窗體類名,窗口名    尋找第index號個同類型的兄弟窗口    """     assert type(index) == int and index >= 0     handle = win32gui.FindWindowEx(pHandle, 0, winClass, winName)     while index > 0        handle = win32gui.FindWindowEx(pHandle, handle, winClass, winName)         index -= 1     return handle

若要獲取任意子窗口的句柄,則可以建立一個索引數(shù)組,然后多次調(diào)用find_idxSubHandle 函數(shù),寫成一個遞歸函數(shù)的形式:

123456789101112def find_subHandle(pHandle, winClassList):     """    遞歸尋找子窗口的句柄    pHandle是祖父窗口的句柄

    winClassList是各個子窗口的class列表,由元組(窗口類名,窗口名,索引號)為元素組成的數(shù)組,父輩的list-index小于子輩

      """ 

    assert type(winClassList) == list     if len(winClassList) == 1        return find_idxSubHandle(pHandle, winClassList[0][0], winClassList[0][1], winClassList[0][2])     else:        pHandle = find_idxSubHandle(pHandle, winClassList[0][0], winClassList[0][1], winClassList[0][2])         return find_subHandle(pHandle, winClassList[1:])

好了,只要能拿到句柄,一切就都好辦了。

按照上一篇中的步驟,一步一步模擬操作就可以了。

1)在下載地址對應(yīng)的文本編輯框中輸入要下載的網(wǎng)址。如下圖所示:

在spy++中可以看出,主程序中一共有2個編輯框,除了下載地址的編輯框,還有就是右下角的那個。并且可以注意到,編輯框的窗口名就是編輯框中的文本,因此在程序運行過程中,改變編輯框的文本,其窗口名就會發(fā)生變化。故只通過類名加索引的方式獲取這個編輯框的句柄。

1edithd=find_subHandle(MHandle,[('Edit',None,1)]) # 下載地址輸入框

模擬向輸入框中輸入網(wǎng)址,可以使用win32gui.SendMessage函數(shù)給輸入框發(fā)送消息。

1win32gui.SendMessage(edithd,win32con.WM_SETTEXT,None,url) # 輸入下載地址

2)點擊 添加任務(wù) 按鈕。

12btAddhd = find_subHandle(MHandle,[('Button',"",2),('Button',u"添加任務(wù)",0)])win32gui.SendMessage(btAddhd,win32con.BM_CLICK,None,None)

這時列表中就會出現(xiàn) 已加入的任務(wù)。

3)點擊 整理任務(wù) 按鈕。

12sorthd=find_subHandle(MHandle,[('Button',u"整理任務(wù)",0)]) #win32gui.SendMessage(sorthd,win32con.BM_CLICK,None,None)

這時列表中會顯示網(wǎng)盤地址和文件ID

待全部解析完后, 整理任務(wù) 按鈕旁邊出現(xiàn) 解析勾選 按鈕。

4)點擊 解析勾選 按鈕

12parsehd=find_subHandle(MHandle,[('Button',u"解析勾選",0)]) #win32gui.PostMessage(parsehd,win32con.BM_CLICK,None,None)

注意,這里使用PostMessage來處理消息。主要是由于點擊 解析勾選 按鈕后,會彈出對話框,如果使用SendMessage,主程序就會阻塞,直至對話框關(guān)閉。而主程序又必須在發(fā)送完消息后捕獲對話框句柄,然后將其關(guān)閉。這就導(dǎo)致了一個死循環(huán),除非人工將對話框關(guān)閉。關(guān)于PostMessage和SendMessage的區(qū)別,如下:

PostMessage(hWnd, Msg, wParam, lParam)描述:在消息隊列中加入為指定的窗體加入一條消息,并馬上返回,不等待線程對消息的處理。參數(shù):hWnd:整型,接收消息的窗體句柄Msg:整型,要發(fā)送的消息,這些消息都是windows預(yù)先定義好的,可以參見系統(tǒng)定義消息(System-Defined Messages))wParam:整型,消息的wParam參數(shù)lParam:整型,消息的lParam參數(shù)說明:簡單說,就是給指定程序發(fā)一個消息,這些消息都用整型編好號,作為windows的常量可以查詢的。在這里,我們用的就是win32con這個庫里定義的WM_COMMAND這個消息,具體的wParam和lParam是根據(jù)消息的不同而不同的。具體請根據(jù)MSDN查閱。

關(guān)于wParam的low Word和high word:

    

查閱MSDN的消息時,會發(fā)現(xiàn)有的wParam定義了low word和high word,這是什么呢?wParam的定義是32位整型,high word就是他的31至16位,low word是它的15至0位,如圖。當(dāng)參數(shù)超過兩個,wParam和lParam不夠用時,可以將wParam就給拆成兩個int16來使用。這種時候在Python里記得用把HIWORD的常數(shù)向左移16位,再加LOWORD,即wParam = HIWORD<<16+LOWORD。

來源: http://blog.csdn.net/seele52/article/details/17542265

 SendMessage(hWnd, Msg, wParam, lParam)

描述:在消息隊列中加入為指定的窗體加入一條消息,直到窗體處理完信息才返回。參數(shù):hWnd:整型,接收消息的窗體句柄Msg:整型,要發(fā)送的消息,這些消息都是windows預(yù)先定義好的,可以參見系統(tǒng)定義消息(System-Defined Messages).aspx#system_defined)wParam:整型,消息的wParam參數(shù)lParam:整型,消息的lParam參數(shù)說明:wParam和iparam根據(jù)具體的消息不同而有不同的定義,詳情參閱Part 2.來源: http://blog.csdn.net/seele52/article/details/17618615

5)關(guān)閉煩人的對話框

上步說過,當(dāng)點擊勾選解析 按鈕時,就會彈出下面的對話框。我們需要點擊 取消 按鈕,或者直接點右下角的關(guān)閉 按鈕。

由于后面還會出現(xiàn)對話框,對于這類只需點擊關(guān)閉按鈕的操作,我們可以寫個函數(shù)封裝。

def closeDialog(win_name):    handle = get_wHandle(u'#32770',win_name) # Dialog的類名為 #32770    PRint(handle)    time.sleep(0.5)    win32gui.SendMessage(handle,win32con.WM_CLOSE,0,0)

def get_wHandle(win_class_name,win_name):  
   while not win32gui.FindWindow(win_class_name, win_name):          time.sleep(0.2)      return win32gui.FindWindow(win_class_name, win_name)然后調(diào)用這個函數(shù), closeDialog(u"是否啟用VIP模式解析")6)選中 全選。    allSelhd=find_subHandle(MHandle,[('Button',"",1),('Button',u"全選",0)]) # ?4F0A4E?    if win32gui.SendMessage(allSelhd,win32con.BM_GETCHECK):        win32gui.SendMessage(allSelhd,win32con.BM_CLICK,None,None)    win32gui.SendMessage(allSelhd,win32con.BM_CLICK,None,None)7)點擊 復(fù)制鏈接 按鈕。    copyhd = find_subHandle(MHandle,[('Button',u"復(fù)制鏈接",0)])    win32gui.PostMessage(copyhd,win32con.BM_CLICK,None,None)此時,又會彈出煩人的對話框。利用前面寫的函數(shù),關(guān)閉對話框。closeDialog(u"復(fù)制成功")8)從系統(tǒng)剪切板中讀取鏈接地址。完成后關(guān)閉程序。    win32clipboard.OpenClipboard()    text = win32clipboard.GetClipboardData(win32clipboard.CF_TEXT)    win32clipboard.CloseClipboard()    win32gui.SendMessage(MHandle,16)注意:1、這些步驟需按順序執(zhí)行,前一個步驟的結(jié)果直接影響下一步的進行。2、由于每一步執(zhí)行需要時間,而每步所需的時間不可預(yù)測,故需要一個狀態(tài)量指示當(dāng)前狀態(tài)。在這個程序中,我們發(fā)現(xiàn)控件 Afx:400000:b:10003:900015:0 的名字每步執(zhí)行完后都會響應(yīng)變化,故可根據(jù)名字來控制程序流的執(zhí)行。--》1--》2--》--》3--》--》4--》5--》--》6--》7--》--》8通過查詢控件名,等待每步執(zhí)行完成。def getState(pHandle):    time.sleep(1)    afx = win32gui.FindWindowEx(pHandle,None,'Afx:400000:b:10003:900015:0',None)    return win32gui.GetWindowText(afx)def waitState(pHandle,msg):    while  msg != getState(pHandle):        time.sleep(0.2)waitState(MHandle,u"請整理任務(wù) →")waitState(MHandle,u"← 請點此解析")waitState(MHandle,u"復(fù)制真實鏈接 →")waitState(MHandle,u"引導(dǎo)完畢..")3. 全部的程序和代碼見我的資源(http://download.csdn.net/detail/shawpan/9755395) 

 

 

  
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 林西县| 乐山市| 宁蒗| 牡丹江市| 当涂县| 曲松县| 和田市| 灌南县| 定日县| 汝城县| 扶沟县| 阿合奇县| 金昌市| 凤山市| 商城县| 周至县| 双鸭山市| 封丘县| 洪江市| 丰镇市| 峨眉山市| 藁城市| 五峰| 隆德县| 清镇市| 连云港市| 綦江县| 凤山县| 松原市| 乌鲁木齐县| 安宁市| 武夷山市| 门头沟区| 岳阳市| 绥滨县| 孟津县| 信宜市| 噶尔县| 封开县| 扬州市| 丰宁|