使用 python 自动从弹出的文件选择对话窗口中,输入指定文件名,并按回车键

文章目录

    目标

    从浏览器中,使用油猴脚本从弹出的系统文件选择框中,选择一个文件,然后提交。

    但是,由于油猴脚本没有访问系统对话窗口的权限,所以只能通过 python 自动化脚本来实现。 参考下面链接里的方案:

    https://stackoverflow.com/questions/17235228/which-is-the-best-way-to-interact-with-already-open-native-os-dialog-boxes-like

    以下是 Windows 下的方案,对于 Ubuntu 桌面系统,介绍在文章最后。

    逻辑

    1. 油猴在浏览器中点击文件选择按钮
    2. 然后调用本地的一个 python 服务
    3. python 服务中调用下面的自动化脚本选择文件

    SendKeys 替换成 pynput

    但是由于 SendKeys 这个库安装总是失败,我又不想浪费时间去折腾,所以改用了 pynput 这个库。

    https://pypi.org/project/pynput/

    安装依赖

    pip install pywin32
    pip install win32gui
    pip install pynput
    

    代码

    例如,在文件选择窗口中,输入 frontend.tar.gz 文件名,然后按两次回车。

    为何按两次回车,可能是我的输入法问题,输入文字总是会唤起微信输入法,所以,这里点两次回车。
    实际上一次就足够。

    import win32gui
    import re
    import time
    from pynput.keyboard import Key, Controller
    
    keyboard = Controller()
    
    
    class WindowFinder:
        """Class to find and make focus on a particular Native OS dialog/Window"""
    
        def __init__(self):
            self._handle = None
    
        def find_window(self, class_name, window_name=None):
            """Pass a window class name & window name directly if known to get the window"""
            self._handle = win32gui. FindWindow(class_name, window_name)
    
        def _window_enum_callback(self, hwnd, wildcard):
            """Call back func which checks each open window and matches the name of window using reg ex"""
            if re.match(wildcard, str(win32gui. GetWindowText(hwnd))) != None:
                self._handle = hwnd
    
        def find_window_wildcard(self, wildcard):
            """This function takes a string as input and calls EnumWindows to enumerate through all open windows"""
            self._handle = None
            win32gui. EnumWindows(self._window_enum_callback, wildcard)
    
        def set_foreground(self):
            """Get the focus on the desired open window"""
            win32gui. SetForegroundWindow(self._handle)
    
    
    win = WindowFinder()
    # win.find_window_wildcard(".*Save As.*")
    win.find_window_wildcard(".*打开.*")
    win.set_foreground()
    # path = "D:\\File.txt"  # Path of the file you want to Save
    # ent = "{ENTER}"  # Enter key stroke.
    # SendKeys.SendKeys(path)  # Use SendKeys to send path string to Save As dialog
    # SendKeys.SendKeys(ent)  # Use SendKeys to send ENTER key stroke to Save As dialog
    
    file = "frontend.tar.gz"
    for i, char in enumerate(file):
        keyboard.press(char)
    time.sleep(1)
    keyboard.press(Key.enter)
    keyboard.release(Key.enter)
    time.sleep(1)
    keyboard.press(Key.enter)
    keyboard.release(Key.enter)
    

    补充安装时遇到的一些错误提示 (可忽略)

    一些错误信息

    ModuleNotFoundError: No module named 'win32gui'
    ModuleNotFoundError: No module named 'win32.distutils.command'
    ModuleNotFoundError: No module named 'SendKeys'
    _sendkeys.c(150): warning C4013: “Py_InitModule”未定义;假设外部返回 int
    

    Ubuntu 下怎么办

    上面是 Windows 系统下的方案,但是如果是在 Ubuntu 桌面系统下,就不能使用 win32 相关的库了。

    可以使用 xdotool 这个库应该可以在 ubuntu 上实现同样的功能:

    https://github.com/jordansissel/xdotool

    xdotool lets you simulate keyboard input and mouse activity, move and resize windows, etc. It does this using X11’s XTEST extension and other Xlib functions.

    参考示例:

    https://askubuntu.com/questions/1336996/how-to-interact-with-zenity-window-and-type-some-text-inside-it

    关于作者 🌱

    我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式