目标
从浏览器中,使用油猴脚本从弹出的系统文件选择框中,选择一个文件,然后提交。
但是,由于油猴脚本没有访问系统对话窗口的权限,所以只能通过 python 自动化脚本来实现。 参考下面链接里的方案:
https://stackoverflow.com/questions/17235228/which-is-the-best-way-to-interact-with-already-open-native-os-dialog-boxes-like
以下是 Windows 下的方案,对于 Ubuntu 桌面系统,介绍在文章最后。
逻辑
- 油猴在浏览器中点击文件选择按钮
- 然后调用本地的一个 python 服务
- 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 聊聊, 查看更多联系方式