Szukając możliwego rozwiązania, natknąłem się na kilka rozwiązań na SO i nie tylko. Niektórzy używali AutoIT
lub przeglądarek edycji profilu, aby zapisać plik bezpośrednio bez wierszu.
znalazłem wszystko to rozwiązanie zbyt szczegółowe jak można przezwyciężyć ten problem na oknie dialogowym Zapisz jako edytując profil przeglądarki, ale jeśli później trzeba obsłużyć jakieś inne okno następnie utkniesz. Do korzystania AutoIT
jest przesadą, to zderza się bezpośrednio na fakt wybiorę Python
aby wykonać to zadanie. (Mam na myśli, że Python
sam jest tak potężny, w zależności od jakiegoś innego narzędzia jest BEZPIECZNY dla jakiegokolwiek Pythonist)
Po długim poszukiwaniu możliwego rozwiązania tego problemu, które nie tylko służy każdemu, kto chce sobie poradzić dowolne okna dialogowe systemu Native OS, takie jak "Zapisz jako", "Przesyłanie plików" itp. w procesie automatyzacji aplikacji internetowej przy użyciu sterownika WWW selenu, ale także dla każdego, kto chce wchodzić w interakcję z określonym oknem, korzystając tylko z interfejsów API Python
.
To rozwiązanie wykorzystuje moduły Win32gui
, z Python
. opiszę najpierw metody rodzajowe zdobyć dowolnym oknie pożądanego następnie niewielką dodanie kodu, który będzie również to użyteczne podczas automatyzowania aplikacji internetowych przy użyciu selen Webdriver.
Generic Rozwiązanie ::
import win32gui
import re
import SendKeys
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.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
Aby użyć tego kodu trzeba dostarczyć łańcuch, który jest nazwa okna, które chcesz dostać, która w tym przypadku jest „Zapisz jako”. Podobnie możesz podać dowolną nazwę i skupić się na tym oknie. Po ustawieniu fokusu żądanego okna można użyć modułu SendKeys
do wysłania pociągnięć klawiszy do okna, które w tym przypadku obejmuje wysyłanie ścieżki do pliku, w którym ma zostać zapisany plik, oraz ENTER
.
Specific do Selenium Webdriver ::
Powyższy określony segment kodu mogą być używane do obsługi natywnych okien dialogowych systemu operacyjnego, które są wywoływane przez aplikację internetową podczas automatyzacji przy użyciu Selenium Webdriver
z dodatkiem odrobiny kodu .
Problem, przed którym stanęł twarzą w twarz podczas korzystania z tego kodu, polega na tym, że po tym, jak kod automatyzacji kliknie na dowolne Web Element
, które uruchamia okno dialogowe rodzimego OS, kontrolka utknie w tym momencie, czekając na dowolną akcję w rodzimym oknie dialogowym OS okno. Więc w zasadzie utknąłeś w tym momencie.
Prace wokół jest, aby wygenerować nowy thread
użyciu Python
threading
moduł i używać go do kliknięcia na Web Element
aby wywołać okno dialogowe OS rodzimych i Twój wątek nadrzędny zostanie przeniesiony na normalnie znaleźć okno przy użyciu kodu pokazałem powyżej.
#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 box
def _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 button
th.start() #Thread starts execution here
time.sleep(1) #Simple Thread Synchronization handle this case.
#Call WindowFinder Class
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 dialog
SendKeys.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 code is doing after this point
UWAGA ::
Podczas korzystania powyższy kod w automatyzację aplikacji internetowych, należy sprawdzić nazwę okna, którą chcesz znaleźć i przekazać, że do find_window_wildcard()
. Nazwa okna zależy od przeglądarki. Na przykład. Okno uruchamiane po kliknięciu elementu do przesłania pliku nazywa się "Przesyłanie pliku" w Firefox
i Otwórz w Chrome
. Wymaga użycia Python2.7
Mam nadzieję, że pomoże to każdemu, kto szuka podobnego rozwiązania, niezależnie od tego, czy używać go w dowolnej formie ogólnej, czy w automatyzacji aplikacji internetowej.
EDIT:
Jeśli próbujesz uruchomić swój kod za pomocą argumentów wiersza poleceń, a następnie spróbuj użyć nici, aby znaleźć okno używając Win32gui
i używać oryginalnego wątku programu kliknąć na elemencie (co jest kliknięto tutaj za pomocą wątku). Powodem jest bibliotekę urllib wygeneruje błąd podczas tworzenia nowego połączenia za pomocą gwintu.)
Referencje ::
SO Question
SenKeys
Win32gui
Jakie są interakcji próbujesz to zrobić? –
@DavidHeffernan Mam aplikację internetową z wyzwalaczami nowe okno Zapisz jako okno dialogowe.Potrzebuję interakcji w tym sensie, że muszę kliknąć na różne opcje obecne w oknie dialogowym i wprowadzić ścieżkę docelową oraz nazwę pliku do zapisania. – abhi
Dlaczego downvote – abhi