首頁 > 後端開發 > Python教學 > 使用Python和pywinauto實現自動化採集任務的步驟和方法

使用Python和pywinauto實現自動化採集任務的步驟和方法

WBOY
發布: 2023-04-26 23:13:17
轉載
1620 人瀏覽過

基於pywinauto 的自動化採集任務

實現技術

這個程式使用了一個Python 的自動化庫---- pywinauto, 因為官方已經很久沒更新了, 所以python 的版本最高只能是Python 3.7 左右, 我用的是Python 3.7.1. 我使用它模擬了輸入單字, 複製例句, 獲取例句, 清空剪切板, 然後重複這個操作, 總體上實現比較簡陋. 而且, 為了簡單, 我是之間手動切換到例句頁, 這樣就不用使用程序來切換到例句頁了.

代碼

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")
# 顺序错误的单词
error_words = []
# 有道词典的进程id
processId = 13840


def line_process(content: str) -> str:
    """
    去除所有空行, 再去除前面四行无关内容
    """
    lines = content.split("\r\n")
    # 因为例句开头是 数字. 开头的, 所以先以这个为特点来进行过滤掉多复制的开头
    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("抓取数据错误")

    content = "\n".join(filter_lines) + "\n"  # 补上一个 \n, 不然正则会漏掉一个结果
    return content


def to_list(line: str) -> List[Dict[str, str]]:
    """
    直接生成列表字典对象
    [{
        "no": 1,
        "original": "",
        "translate"
    }]
    """
    sentences = []
    # 正则表达式
    REGEXP = r&#39;(?P<no>\d+?)\.\n(?P<original>.+?)\n(?P<translate>.+?)\n&#39;
    # 编译
    pattern = re.compile(REGEXP)
    # 匹配
    rs = pattern.finditer(line)
    # 组装结果
    for r in rs:
        print(r.groupdict())
        sentences.append(r.groupdict())
    return sentences


if __name__ == "__main__":
    # 连接网易有道词典
    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)
        # 清空剪切板,这步很重要,防止重复复制
        pyperclip.copy("")
        # 将输入数据复制到剪切板
        pyperclip.copy(word)
        # 定位到输入框(采用坐标定位,定位到大致位置即可)
        mouse.click(coords=(2400, 80))
        # 模拟按键操作:全选 删除 粘贴 回车(触发查询)
        keyboard.send_keys("^a{DELETE}^v{ENTER}")
        # 清空剪切板,这步很重要,防止重复复制
        pyperclip.copy("")
        # 鼠标左键点击,这个操作只是为了把鼠标移动到这里
        mouse.click(button="left", coords=(2200, 330))
        # 模拟键盘 CTRL+A CTRL+C,直接全选所有的例句(这里会多选一部分内容,待会再处理)
        keyboard.send_keys("^a^c")
        # 暂停一会儿,不做操作的太快
        time.sleep(random.random() * 2 + 1)
        # pywinauto 复制的内容是在系统的剪切板里面的,所以需要其它库读取
        content = pyperclip.paste()
        # 对内容进行简单的预处理后,加入output_words
        try:
            lines = line_process(content)
        except BaseException as exp:
            print(exp)
            # 如果抓取出现问题,说明被网易抓了现行,直接退出即可。
            break

        sentences = to_list(lines)
        if not sentences:
            print("获取例句为空, 可能是数据格式错误.")
            break
        output_words.append({
            "word": word,
            "example": sentences,
        })
        # 模拟暂停一个较长的随机时间,没有必要追求速度,平稳运行即可。
        time.sleep(random.random() * 3 + 3)
        # 清空剪切板,这步很重要,防止重复复制
        pyperclip.copy("")

    # 抓取完毕一个文件的内容后,然后一次性写入即可。
    # 之前的写法是一个单词写入一次,会造成太多的IO次数,浪费性能!
    with open(output_path, "a+", encoding="utf-8") as output_file:
        output_file.write(json.dumps(
            output_words, ensure_ascii=False, indent=4))

        # 错误单词记录
        with open(error_path, "w", encoding="utf-8") as err_file:
            err_file.writelines("\n".join(error_words))
登入後複製

示範 如果想要啟動這個程式碼, 還是蠻複雜的. 我這裡直接把需要的步驟羅列一下, 希望能幫助感有興趣的同學.

  1. 修改dir_path, 並且在下面準備一個input.txt 檔案.

  2. 取得有道字典進程的id.

  3. 取得單字輸入框的座標, 取得複製貼上處的座標.

  4. 將有道字典介面調整到例句處.

啟動專案, 需要一個

input.txt 檔案, 這裡是我測試的檔案.

sophisticated

centralization
phenomenon
internationalization
radioactive

我是透過工作管理員取得的進程pid, 你也可以透過它存取. 或者最簡單的是使用Inspect 和Spy , 我這裡就偷懶了, 直接怎麼省事怎麼來了.

使用Python和pywinauto實現自動化採集任務的步驟和方法

單字輸入框的座標, 複製貼上處的座標. 第一個座標是為了定位輸入框的, 然後程式會把單字複製進去, 並執行一下回車鍵, 然後內容被查詢出來. 再將滑鼠移動到第二個座標處, 這裡只是移動到下面的空白處就行了, 然後會執行一個全選CTRL A 操作. 這樣一個單字的內容就全部獲取到了.

使用Python和pywinauto實現自動化採集任務的步驟和方法

將有道調整到這個位置, 首選查詢一個單字, 選擇例句, 然後保持這個介面不要動即可.

使用Python和pywinauto實現自動化採集任務的步驟和方法

最後就是程式的執行了, 錄製的GIF 做了加速處理, 實際上執行的時候, 是特意加了延時的, 防止被過早的發現了.

使用Python和pywinauto實現自動化採集任務的步驟和方法

控制台輸出

使用Python和pywinauto實現自動化採集任務的步驟和方法

#output.json 檔案

使用Python和pywinauto實現自動化採集任務的步驟和方法

以上是使用Python和pywinauto實現自動化採集任務的步驟和方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:yisu.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板