与使用Python与已打开的本机OS对话框(例如(另存为AS))进行交互的最佳方法是什么?

与使用Python与已打开的本机OS对话框(例如(另存为AS))进行交互的最佳方法是什么?,第1张

与使用Python与已打开的本机OS对话框(例如(另存为AS))进行交互的最佳方法是什么?

在为此寻找可能的解决方案时,我遇到了关于SO和其他方面的几种解决方案。其中一些使用

AutoIT
,或编辑浏览器配置文件以使其直接存储文件而没有提示。

我发现所有这些解决方案都太具体了,以至于您可以通过编辑浏览器配置文件来解决“另存为”对话框的问题,但是如果以后需要处理其他窗口,则会遇到麻烦。因为使用

AutoIT
是多余的,这直接冲突了我选择
Python
执行此任务的事实。(我是
Python
说它本身是如此强大,取决于任何其他工具,对于任何Pythonist来说都是严格禁止的)

因此,在长期寻找这一问题的可能解决方案之后,该解决方案不仅可以为使用硒自动执行Web应用程序过程中希望处理任何本机OS对话框(如“另存为”,“文件上传”等)的任何人提供服务Web驱动程序,也适用于希望仅使用

Python
API与特定窗口进行交互的任何人。

该解决方案利用了

Win32gui
SendKeys
的模块
Python
。首先,我将解释一种通用方法,该方法可获取所需的任何窗口,然后添加少量代码,这将在使用Selenium
Webdriver自动执行Web应用程序时使此方法可用。

通用解决方案 ::

import win32guiimport reimport SendKeysclass 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.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 dialogSendKeys.SendKeys(ent)#Use SendKeys to send ENTER key stroke to Save As dialog

要使用此代码,您需要提供一个字符串,该字符串是您要获取的窗口的名称,在这种情况下为“另存为”。因此,类似地,您可以提供任何名称并使该窗口聚焦。一旦将焦点放在所需的窗口上,便可以使用

SendKeys
模块将击键发送到窗口,在这种情况下,包括将文件路径发送到要保存文件的位置和
ENTER

特定于Selenium Webdriver ::

上面指定的代码段可用于处理本机OS对话框,这些对话框是在自动化过程中通过使用

Selenium Webdriver
少量的代码通过Web应用程序触发的。

我在使用此代码时会遇到的问题是,一旦您的自动化代码单击了任何

WebElement
会触发本机OS对话框窗口的代码,控件将停留在该位置,等待对本机OS对话框窗口的任何 *** 作。因此,基本上,您在这一点上陷入了困境。

解决方法是生成一个新的

thread
using
Python
threading
模块,并使用它单击
WebElement
触发本机OS对话框,并且您的父线程将正常运行以使用上面显示的代码查找窗口。

#Assume that at this point you are on the page where you need to click on a Web Element to trigger native OS window/dialog boxdef _action_on_trigger_element(_element):    _element.click()trigger_element = driver.find_element_by_id('ID of the Web Element which triggers the window')th = threading.Thread(target = _action_on_trigger_element, args = [trigger_element])  #Thread is created here to call private func to click on Save buttonth.start()    #Thread starts execution heretime.sleep(1) #Simple Thread Synchronization handle this case.#Call WindowFinder Classwin = WindowFinder()win.find_window_wildcard(".*Save As.*") 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 dialogSendKeys.SendKeys(ent)#Use SendKeys to send ENTER key stroke to Save As dialog#At this point the native OS window is interacted with and closed after passing a key stroke ENTER.# Go forward with what ever your Automation pre is doing after this point

注意::

在自动化Web应用程序中使用上述代码时,请检查您要查找的窗口的名称并将其传递给

find_window_wildcard()
。Windows的名称取决于浏览器。例如,当您单击元素上载文件时触发的窗口称为“文件上载”
Firefox
和“打开中”
Chrome
。用途
Python2.7

我希望这对正在寻找类似解决方案的任何人(无论是以任何通用形式使用它还是使Web应用程序自动化)都将有所帮助。

编辑:

如果您尝试通过命令行参数运行代码,则尝试使用该线程来查找窗口,

Win32gui
并使用原始程序线程单击该元素(在此处使用该线程单击该元素)。原因是urllib库在使用线程创建新连接时会引发错误。)

参考文献:

所以问题

森基斯

Win32gui



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5631900.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-15
下一篇 2022-12-15

发表评论

登录后才能评论

评论列表(0条)

保存