今天遇到的问题过程:
-
selenium与系统弹窗
使用selenium进行网页操作时,需要选择文件,点击某个按钮后,出现了系统的文件选择框,此时,无法使用selenium进行文件选择。 -
通过pyautogui
pyautogui.typewrite()是PyAutoGUI库中的一个函数,用于模拟键盘输入。
通过这个函数,可以把文件路径打出来,然后回车,实现文件选择的作用。
def fileSelect(input):
pyautogui.typewrite(input)
pyautogui.hotkey('enter')
此时遇到了下一个问题,就是typewrite如果遇到中文就不行了。
- 通过pyperclip
pyperclip是一个Python库,它提供了在剪贴板(Clipboard)中复制和粘贴文本的功能。
def fileSelect(input):
pyperclip.copy(input)
time.sleep(1)
pyautogui.hotkey('Ctrl', 'V')
pyautogui.hotkey('enter')
此时又出现了一个问题,就是当这个程序在云服务器上运行,没办法使用剪切板的,远程主机连着的时候可以正常使用,只要和远程主机已断开,就挂了。
- 通过win32gui
win32gui提供了访问GUI的功能,包括窗口和控件的管理。
那么就可以通过监测系统弹窗的方式,对弹窗进行操作。
import win32gui
import win32con
import win32api
# 定义常量
WM_SETTEXT = win32con.WM_SETTEXT
WM_GETTEXT = win32con.WM_GETTEXT
WM_COMMAND = win32con.WM_COMMAND
BN_CLICKED = win32con.BN_CLICKED
def operate_windows_popup(window_title, text):
# 查找窗口句柄
handle = win32gui.FindWindow(None, window_title)
if handle != 0:
# 找到弹框内文本框的句柄
edit_box_handle = win32gui.FindWindowEx(handle, None, 'Edit', None)
if edit_box_handle != 0:
# 输入文本
win32api.SendMessage(edit_box_handle, WM_SETTEXT, None, text)
# 找到打开按钮的句柄
open_button_handle = win32gui.FindWindowEx(handle, None, 'Button', '打开')
if open_button_handle != 0:
# 点击打开按钮
win32api.SendMessage(open_button_handle, WM_COMMAND, BN_CLICKED, 0)
比起刚才,多了一个参数,除了需要输入的文件路径,还多了一个窗口名称,比如我的窗口叫“打开”,按钮也叫“打开”。
那么我的函数就像上面这样写。
又又又出现了一个问题,就是能找到父窗口(文件选择框),但是找不到父窗口下的输入框和打开按钮。
我用win32gui.EnumChildWindows
遍历打印了父窗口下的所有子窗口,发现是有’Edit’和’Button’的,但是就是找不到。
网上一些伙伴说“直接子级”的原因或其他,但是最后也找不到什么办法。
所以我只能曲线救国,既然遍历的时候能找到,那就在遍历的时候直接操作吧(仅适用于简单的操作,比如选择文件)
def enum_child_callback(hwnd, lParam):
# 获取窗口类名和文本
class_name = win32gui.GetClassName(hwnd)
if class_name == "Edit":
# 向子窗口发送文本
win32gui.SendMessage(hwnd, win32con.WM_SETTEXT, None, lParam)
if class_name == "Button":
# 获取按钮的文本
button_text = win32gui.GetWindowText(hwnd)
if "打开" in button_text:
# 点击按钮
win32gui.PostMessage(hwnd, win32con.BM_CLICK, 0, 0)
# 操作系统弹窗函数
import win32gui
import win32con
# 定义常量
WM_SETTEXT = win32con.WM_SETTEXT
WM_GETTEXT = win32con.WM_GETTEXT
WM_COMMAND = win32con.WM_COMMAND
BN_CLICKED = win32con.BN_CLICKED
def operate_windows_popup(window_title, text):
# 查找窗口句柄
handle = win32gui.FindWindow(None, window_title)
if handle != 0:
win32gui.EnumChildWindows(handle, enum_child_callback, text)
到这里解决完了。