0.關鍵實現:程序窗口前置
python 通過js控制滾動條拉取全文 通過psutil獲取pid窗口句柄,通過win32gui使程序窗口前置 通過pyauto實現右鍵菜單和另存為操作
1.參考
- autopy (實踐見最后一章節)
AutoPy Introduction and Tutorial
autopy.mouse.smooth_move(1, 1) 可以實現平滑移動
- pip install PyUserInput
[python3.5][PyUserInput]模擬鼠標和鍵盤模擬
- autoit
selenium webdriver 右鍵另存為下載文件(結合robot and autoIt)
- win32api
- pyautowin
https://pyautogui.readthedocs.io/en/latest/
- 其他PyAutoGUI等。。。
2.下載地址
https://en.uptodown.com/windows/automatization >> https://tinytask.en.uptodown.com/windows
https://www.autoitscript.com/site/autoit/downloads/
3.工具簡介
(1)GhostMouse導出文件可讀,可以通過腳本提取鼠標軌跡和鍵盤輸入內容。但是通過命令行運行所導出的文件,只是自動打開程序,還需要通過快捷鍵運行回放。
(2)tinytask導出文件不可讀,可以導出編譯好的exe,通過命令行可以直接無界面回放。
Python執行系統命令,os.system && os.popen && subprocess.Popen
4.python調用外部腳本或程序(如tinytask)
import subprocess def run_tinytask(rec_file_compiled): # 運行外部腳本,傳入參數和接受print內容 # p = subprocess.Popen(['python','xxx.py','-n',sth_to_pass],stdout=subprocess.PIPE) # result = p.stdout.read() # 參考pytesseract.py command = [rec_file_compiled] # proc = subprocess.Popen(command, stderr=subprocess.PIPE) proc = subprocess.Popen(command) status = proc.wait() # error_string = proc.stderr.read() # proc.stderr.close() # print status, error_string return status def main(): rec_file_compiled = 'G:/pydata/install/test.exe' # tinytask導出的編譯文件 print run_tinytask(rec_file_compiled) print 'finished' if __name__ == '__main__': main()
5.通過腳本提取GhostMouse記錄的鼠標軌跡和鍵盤輸入內容
(1)參考
滑動驗證碼破解:Python Selenium 2.0 應用
(2)代碼實現
#coding:utf-8 # GhostMouse導出的rms文件 # {Delay 2.13} # {Move (1225,349)} # {Delay 0.23} # {Move (729,657)} # {Delay 1.65} # {LMouse down (727,658)} #鼠標按下開始拖動 # {Delay 0.99} # {Move (727,658)} # {Delay 0.11} # {Move (790,659)} # {Delay 0.91} # {LMouse up (790,659)} #鼠標釋放結束拖動 import os # xyd_typical = (1,0,0.04) def read_rms(file_rms): with open(file_rms) as fp: #os.path.sep LMouse_down = False for line in fp: #{LMouse down (727,658)} # {Delay 1.65} if 'LMouse down' in line or (LMouse_down == True and 'Move' in line): if 'LMouse down' in line: LMouse_down = True xyd_records = [] x_last, y_last = 0, 0 #保證第一個偏移量為實際開始位置 xy_pos = line.split('(')[1].split(')')[0].split(',') x_pos, y_pos = [int(i) for i in xy_pos] continue # {Move (729,657)} # {Delay 1.65} if LMouse_down == True and 'Delay' in line: x_delta, y_delta = x_pos-x_last, y_pos-y_last if x_delta == 0 and y_delta == 0 and len(xyd_records) != 0: #len 可能起點就是0,0 continue else: delay = float(line.split(' ')[1].split('}')[0]) xyd_records.append((x_delta, y_delta, delay)) x_last, y_last = x_pos, y_pos continue # {LMouse up (790,659)} if LMouse_down == True and 'LMouse up' in line: # x_init y_init x_change y_change # x y d 每一次偏移量 # x y d with open(file_txt,'a') as fh_txt: # x_change = sum(x for x,y,d in xyd_records) x_init = xyd_records[0][0] y_init = xyd_records[0][1] x_change = sum(x for x,y,d in xyd_records[1:]) y_change = sum(y for x,y,d in xyd_records[1:]) fh_txt.write('{} {} {} {}\n'.format(x_init, y_init, x_change, y_change)) #加os.linesep是'\r\n' for x,y,d in xyd_records[1:]: #第一個記錄為起始位置,value記錄之后的每一次偏移 fh_txt.write('{} {} {}\n'.format(x, y, d)) LMouse_down = False xyd_records = [] def read_txt(file_txt): with open(file_txt,'r') as fp: result = {} #(x_init, y_init, x_change, y_chang): [(x0,y0,d0), (x1,y1,d1)...] for line in fp: line = line.strip().split() if len(line) == 4: key = tuple([int(i) for i in line]) result[key] = [] elif len(line) == 3: x,y,d = line x,y,d = int(x), int(y), float(d) result[key].append((int(x), int(y), float(d))) return result if __name__ == '__main__': file_rms = os.path.join(os.path.abspath('.'),'mouse.rms') file_txt = os.path.join(os.path.abspath('.'),'mouse.txt') read_rms(file_rms) result = read_txt(file_txt) for k,v in result.items(): print k,v
6.selenium+autopy實現右鍵另存為
#!/usr/bin/env python # -*- coding: UTF-8 -* import time from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains # import autopy from autopy import key, mouse driver = webdriver.Chrome() # driver = webdriver.Firefox() driver.get('http://www.baidu.com') # <a class="mnav" href="http://news.baidu.com" name="tj_trnews">新聞</a> e = driver.find_element_by_partial_link_text(u'新聞') #頁面顯示的鏈接文字,而不是具體鏈接地址,所以'news'不行!!! # e = driver.find_element_by_name('tj_trnews') # fifefox geckodriver context_click異常 # https://stackoverflow.com/questions/6927229/context-click-in-selenium-2-2 # http://bbs.csdn.net/topics/392058306 # https://stackoverflow.com/questions/40360223/webdriverexception-moveto-did-not-match-a-known-command ActionChains(driver).context_click(e).perform() # ActionChains(driver).move_to_element(e).context_click(e).perform() #也行 # mouse.click(mouse.RIGHT_BUTTON) time.sleep(1.5) key.type_string('k') time.sleep(1.5) key.type_string(time.strftime('%H%M%S')) key.tap(key.K_RETURN)