Python基于pywinauto實(shí)現(xiàn)的自動化采集任務(wù)
基于 pywinauto 的自動化采集任務(wù)
實(shí)現(xiàn)技術(shù)代碼總結(jié) 這是一篇學(xué)習(xí)總結(jié), 前段時(shí)間寫了一個(gè)基于 Python 的自動獲取網(wǎng)易有道單詞例句的程序, 效果感覺還不錯(cuò). 但是最終我也沒有使用它, 主要原因有以下三點(diǎn):
- 獲取速度太慢, 我想要獲取的單詞比較多.
- 網(wǎng)易也會對這種行為進(jìn)行封禁的, 采集會中斷.
- 這些例句是有屬于網(wǎng)易的.
實(shí)現(xiàn)技術(shù)
這個(gè)程序使用了一個(gè) Python 的自動化庫 ---- pywinauto, 因?yàn)楣俜揭呀?jīng)很久沒更新了, 所以 python 的版本最高只能是 Python 3.7 左右, 我用的是 Python 3.7.1. 我使用它模擬了輸入單詞, 復(fù)制例句, 獲取例句, 清空剪切板, 然后重復(fù)這個(gè)操作, 總體上實(shí)現(xiàn)比較簡陋. 而且, 為了簡單, 我是之間手動切換到例句頁, 這樣就不用使用程序來切換到例句頁了.
代碼
requirements.txt
pyperclip==1.8.2 pywin32==304 pywinauto==0.6.8
代碼
import os
import random
import time
import re
from typing import Dict, List
from pywinauto.application import Application
from pywinauto import mouse
from pywinauto import keyboard
import pyperclip
import json
# 程序處理中的各種路徑
dir_path = r"C:/Users/Dick/Desktop/work/DragonEnglish/tools"
input_path = os.path.join(dir_path, r"input.txt")
output_path = os.path.join(dir_path, r"output.json")
error_path = os.path.join(dir_path, r"error.txt")
# 順序錯(cuò)誤的單詞
error_words = []
# 有道詞典的進(jìn)程id
processId = 13840
def line_process(content: str) -> str:
"""
去除所有空行, 再去除前面四行無關(guān)內(nèi)容
"""
lines = content.split("\r\n")
# 因?yàn)槔溟_頭是 數(shù)字. 開頭的, 所以先以這個(gè)為特點(diǎn)來進(jìn)行過濾掉多復(fù)制的開頭
count = 0
for i in range(len(lines)):
if re.match(r"\d+\.", lines[i]):
count = i
break
lines = lines[count:]
filter_lines = []
for line in lines:
if line.strip() != "": # 過濾空行
if not line.startswith("youdao") and not \
(line.startswith("《") and line.endswith("》")): # 過濾來源
filter_lines.append(line)
if len(filter_lines) % 3 != 0:
raise Exception("抓取數(shù)據(jù)錯(cuò)誤")
content = "\n".join(filter_lines) + "\n" # 補(bǔ)上一個(gè) \n, 不然正則會漏掉一個(gè)結(jié)果
return content
def to_list(line: str) -> List[Dict[str, str]]:
"""
直接生成列表字典對象
[{
"no": 1,
"original": "",
"translate"
}]
"""
sentences = []
# 正則表達(dá)式
REGEXP = r'(?P<no>\d+?)\.\n(?P<original>.+?)\n(?P<translate>.+?)\n'
# 編譯
pattern = re.compile(REGEXP)
# 匹配
rs = pattern.finditer(line)
# 組裝結(jié)果
for r in rs:
print(r.groupdict())
sentences.append(r.groupdict())
return sentences
if __name__ == "__main__":
# 連接網(wǎng)易有道詞典
app = Application(backend="uia").connect(process=processId)
# 獲取需要的窗口
win = app.window(class_name="RICHEDIT50W")
# 輸入詞匯列表
input_words = []
# 輸出詞匯對象列表
output_words = []
# 打開輸入文件,初始化輸入詞匯列表
with open(input_path, "r", encoding="utf-8") as input_file:
input_words = input_file.read().split("\n")
for word in input_words:
print("正在抓取單詞: %s" % word)
# 清空剪切板,這步很重要,防止重復(fù)復(fù)制
pyperclip.copy("")
# 將輸入數(shù)據(jù)復(fù)制到剪切板
pyperclip.copy(word)
# 定位到輸入框(采用坐標(biāo)定位,定位到大致位置即可)
mouse.click(coords=(2400, 80))
# 模擬按鍵操作:全選 刪除 粘貼 回車(觸發(fā)查詢)
keyboard.send_keys("^a{DELETE}^v{ENTER}")
# 清空剪切板,這步很重要,防止重復(fù)復(fù)制
pyperclip.copy("")
# 鼠標(biāo)左鍵點(diǎn)擊,這個(gè)操作只是為了把鼠標(biāo)移動到這里
mouse.click(button="left", coords=(2200, 330))
# 模擬鍵盤 CTRL+A CTRL+C,直接全選所有的例句(這里會多選一部分內(nèi)容,待會再處理)
keyboard.send_keys("^a^c")
# 暫停一會兒,不做操作的太快
time.sleep(random.random() * 2 + 1)
# pywinauto 復(fù)制的內(nèi)容是在系統(tǒng)的剪切板里面的,所以需要其它庫讀取
content = pyperclip.paste()
# 對內(nèi)容進(jìn)行簡單的預(yù)處理后,加入output_words
try:
lines = line_process(content)
except BaseException as exp:
print(exp)
# 如果抓取出現(xiàn)問題,說明被網(wǎng)易抓了現(xiàn)行,直接退出即可。
break
sentences = to_list(lines)
if not sentences:
print("獲取例句為空, 可能是數(shù)據(jù)格式錯(cuò)誤.")
break
output_words.append({
"word": word,
"example": sentences,
})
# 模擬暫停一個(gè)較長的隨機(jī)時(shí)間,沒有必要追求速度,平穩(wěn)運(yùn)行即可。
time.sleep(random.random() * 3 + 3)
# 清空剪切板,這步很重要,防止重復(fù)復(fù)制
pyperclip.copy("")
# 抓取完畢一個(gè)文件的內(nèi)容后,然后一次性寫入即可。
# 之前的寫法是一個(gè)單詞寫入一次,會造成太多的IO次數(shù),浪費(fèi)性能!
with open(output_path, "a+", encoding="utf-8") as output_file:
output_file.write(json.dumps(
output_words, ensure_ascii=False, indent=4))
# 錯(cuò)誤單詞記錄
with open(error_path, "w", encoding="utf-8") as err_file:
err_file.writelines("\n".join(error_words))
演示 如果想要啟動這個(gè)代碼, 還是蠻復(fù)雜的. 我這里直接把需要的步驟羅列一下, 希望能幫助感興趣的同學(xué).
- 修改dir_path, 并且在下面準(zhǔn)備一個(gè) input.txt 文件.
- 獲取有道詞典進(jìn)程的 id.
- 獲取單詞輸入框的坐標(biāo), 獲取復(fù)制粘貼處的坐標(biāo).
- 將有道詞典界面調(diào)整到例句處.
啟動項(xiàng)目, 需要一個(gè) input.txt 文件, 這里是我測試的文件.
sophisticated
centralization
phenomenon
internationalization
radioactive
我是通過任務(wù)管理器獲取的進(jìn)程 pid, 你也可以通過其它訪問. 或者最簡單的是使用 Inspect 和 Spy++, 我這里就偷懶了, 直接怎么省事怎么來了.

單詞輸入框的坐標(biāo), 復(fù)制粘貼處的坐標(biāo). 第一個(gè)坐標(biāo)是為了定位輸入框的, 然后程序會把單詞復(fù)制進(jìn)去, 并執(zhí)行一下回車鍵, 然后內(nèi)容被查詢出來. 再將鼠標(biāo)移動到第二個(gè)坐標(biāo)處, 這里只是移動到下面的空白處就行了, 然后會執(zhí)行一個(gè)全選 CTRL+A 操作. 這樣一個(gè)單詞的內(nèi)容就全部獲取到了.

將有道調(diào)整到這個(gè)位置, 首選查詢一個(gè)單詞, 選擇例句, 然后保持這個(gè)界面不要?jiǎng)蛹纯?

最后就是程序的執(zhí)行了, 錄制的 GIF 做了加速處理, 實(shí)際上執(zhí)行的時(shí)候, 是特意加了延時(shí)的, 防止被過早的發(fā)現(xiàn)了.

控制臺輸出

output.json 文件

總結(jié)
這個(gè)雖然沒有什么用處, 不過也了解了不少新的東西. 在這個(gè)過程中學(xué)習(xí)了正則表達(dá)式, 并且也運(yùn)用上了. 如果你關(guān)注我的其它博客的話, 會發(fā)現(xiàn)我最近一直在更新正則表達(dá)式相關(guān)的文章. 這個(gè)就是一個(gè)小玩具, 不過如果真的要啟動的話, 我感覺還蠻麻煩的, 如果感興趣的話, 不妨試一試. 如果有問題的話, 可以在下面評論. 不過不一定可以及時(shí)回復(fù)了.
到此這篇關(guān)于Python基于pywinauto實(shí)現(xiàn)的自動化采集任務(wù)的文章就介紹到這了,更多相關(guān)pywinauto實(shí)現(xiàn)自動化采集內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Flask框架 CSRF 保護(hù)實(shí)現(xiàn)方法詳解
這篇文章主要介紹了Flask框架 CSRF 保護(hù)實(shí)現(xiàn)方法,結(jié)合實(shí)例形式詳細(xì)分析了Flask-WTF針對CSRF攻擊的防護(hù)相關(guān)操作技巧,需要的朋友可以參考下2019-10-10
Python英文文章詞頻統(tǒng)計(jì)(14份劍橋真題詞頻統(tǒng)計(jì))
這篇文章主要介紹了Python英文文章詞頻統(tǒng)計(jì)(14份劍橋真題詞頻統(tǒng)計(jì)),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10
python實(shí)現(xiàn)自動化報(bào)表功能(Oracle/plsql/Excel/多線程)
這篇文章主要介紹了python實(shí)現(xiàn)自動化報(bào)表(Oracle/plsql/Excel/多線程)的相關(guān)知識,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12
windows下安裝Python虛擬環(huán)境virtualenvwrapper-win
這篇文章主要介紹了windows下安裝Python虛擬環(huán)境virtualenvwrapper-win,內(nèi)容超簡單,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-06-06
Python 中的 import 機(jī)制之實(shí)現(xiàn)遠(yuǎn)程導(dǎo)入模塊
模塊導(dǎo)入( import ),是指在一個(gè)模塊中使用另一個(gè)模塊的代碼的操作,它有利于代碼的復(fù)用。這篇文章主要介紹了Python 的 import 機(jī)制:實(shí)現(xiàn)遠(yuǎn)程導(dǎo)入模塊,需要的朋友可以參考下2019-10-10
win系統(tǒng)下為Python3.5安裝flask-mongoengine 庫
MongoEngine 是一個(gè)用來操作 MongoDB 的 ORM 框架,如果你不知道什么是 ORM,可以參考 Flask-SQLAlchemy 一節(jié)。在 Flask 中,我們可以直接使用 MongoEngine,也可使用 Flask-MongoEngine ,它使得在 Flask 中使用 MongoEngine 變得更加簡單。2016-12-12

