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

更新日期: 2024-10-23 阅读次数: 317 字数: 648 分类: 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 聊聊, 查看更多联系方式