2013-07-19 32 views
8

Używam Selenium z Pythonem i Chrome. Próbuję przytrzymać różne klawisze - szczególnie "w, a, s i d". Znalazłem akcję Selenium action_chains.key_press oraz metodę elem.send_keys. Problem z pierwszą metodą polega na tym, że przytrzymuje on klucz tylko tak długo, jak długo trwa ukończenie łańcucha działań. Problem z metodą elem.send_keys polega na tym, że nie ma elementu, do którego można by wysłać klucze.Jak trzymać klucz przy pomocy Selenium

Próbuję kontrolować robota opartego na przeglądarce internetowej za pomocą W-A-S-D, więc muszę trzymać klawisze w dół przez różne okresy.

Próbowałem następujące:

action_chains = ActionChains(driver) 
action_chains.key_down("w") 
action_chains.key_up("w") 

, jak:

action_chains.key_press(elem, "w") 
for x in range (0, 100): 
    action_chains.perform() 
    time.sleep(.01) 

Ani są idealne.

+0

Wystarczy, aby potwierdzić, mówisz, że 'action_chains.key_down ("W")' nie praca? A może potrzebujesz metody podnoszenia klucza po pewnym czasie? – alex

+0

'action_chains.key_down (" w ")' działa, ale tylko na ułamek sekundy, który zajmuje komputerowi wykonanie tej akcji. Oczywiście projektanci paczki sprawili, że zajmuje to jak najmniej czasu.Potrzebuję sposobu, aby go przytrzymać, a następnie zwolnić po pewnym czasie. –

+0

Możliwy duplikat [Python symuluje keydown] (http://stackoverflow.com/questions/11906925/python-simulate-keydown) – Yuu

Odpowiedz

0

Łańcuch akcji selenu Może być używany tylko z klawiszami modyfikującymi (Control, Alt i Shift). Więc chcesz nacisnąć tylko postać w-a-s-d. więc to nie zadziałało.

Można używać żadnych narzędzi automatyzacji gui jak pyautogui itp

spróbuj poniżej kod i daj mi znać.

import pyautogui 

pyautogui.PAUSE = 10 
pyautogui.keyDown('w') 
pyautogui.keyUp('w') 

pyautogui.PAUSE = 10 Komenda zrobić pauzę po 10 sekund każdy PyAutoGUI zadzwonić

+0

Potrzebuję jakiegoś możliwego rozwiązania na Selenium. Aby upewnić się, że ta akcja pojawia się tylko w Web PageWindow. Ale nie w innych miejscach. – GensaGames

+0

Ta akcja ma miejsce w miejscu, w którym znajduje się kursor. Przed tym kodem możesz aktywować okno przeglądarki używając selenu. A działanie łańcucha selenu wymaga, aby brower był górnym oknem. W przeciwnym razie obsługa klawiatury i myszy nie będzie działać. – Murthi

+0

Nie użyłem wcześniej akcji Action Chain, ale inne działania, takie jak WebDriver.send_keys(), działają bez problemu, gdy tylko okno Chrome jest ukryte. – GensaGames

0

Według Selenium Documentation dla key_down, stwierdza:

powinny być używane tylko z klawiszy modyfikujących (kontrola , Alt i Shift).

Przeszukałem dokumentację pod kątem rozwiązania alternatywnego, ale wygląda na to, że zachowanie "przytrzymaj" klawiszy niemodyfikowania nie jest możliwe w Selenium.

+0

To jest jak ostrzeżenie w Selenium. Wywołanie 'key_down' działa dla innych kluczy, ale tylko tak, jak klikanie, a nie trzymanie (i nie wiem, dlaczego). – GensaGames

+0

@GensaGames Czasami (niestety) odpowiedź na tego typu pytania brzmi po prostu "To niemożliwe". Możesz z pewnością zażądać tego jako nowej funkcji lub samemu udostępnić tę funkcję tutaj: https://github.com/SeleniumHQ/www.seleniumhq.org/issues –

+0

@GensaGames Czy możesz opisać zachowanie, które próbujesz przetestować? –

2

Aktualny sterownik dla Chrome (wersja 2.30) implementuje poprzedni protokół, w którym trzymanie klucza jest obsługiwane tylko dla klawisza modyfikującego (Control, Shift, Alt, Command).

Więc ten kod działa z Firefoksem ale nie z Chrome ponieważ zdarzenie keyUp jest emitowany za każdym keyDown:

action_key_down_w = ActionChains(driver).key_down("w") 
action_key_up_w = ActionChains(driver).key_up("w") 

endtime = time.time() + 1.0 

while True: 
    action_key_down_w.perform() 

    if time.time() > endtime: 
    action_key_up_w.perform() 
    break 

Ale od wersji 2.30, kierowca Chrome obsługuje send_command bezpośrednio wysłać surowe polecenie za pośrednictwem protokołu devtools. W celu obejścia tego problemu można zadzwonić pod numer Input.dispatchKeyEvent, aby emitować zdarzenia o niskim poziomie.

To jest przykład pracy z selenem/Chrome do przytrzymaj klawisz w podczas drugiego:

from selenium import webdriver 
import json, time 

def dispatchKeyEvent(driver, name, options = {}): 
    options["type"] = name 
    body = json.dumps({'cmd': 'Input.dispatchKeyEvent', 'params': options}) 
    resource = "/session/%s/chromium/send_command" % driver.session_id 
    url = driver.command_executor._url + resource 
    driver.command_executor._request('POST', url, body) 

def holdKeyW(driver, duration): 
    endtime = time.time() + duration 
    options = { \ 
    "code": "KeyW", 
    "key": "w", 
    "text": "w", 
    "unmodifiedText": "w", 
    "nativeVirtualKeyCode": ord("W"), 
    "windowsVirtualKeyCode": ord("W") 
    } 

    while True: 
    dispatchKeyEvent(driver, "rawKeyDown", options) 
    dispatchKeyEvent(driver, "char", options) 

    if time.time() > endtime: 
     dispatchKeyEvent(driver, "keyUp", options) 
     break 

    options["autoRepeat"] = True 
    time.sleep(0.01) 


driver = webdriver.Chrome() 
driver.get("https://stackoverflow.com/questions") 

# set the focus on the targeted element 
driver.find_element_by_css_selector("input[name=q]").click() 

# press the key W during a second 
holdKeyW(driver, 1.0) 
+0

Doskonale! Tymczasem korzystanie z Firefoksa jest OK, ale dlaczego te informacje są wszędzie niedostępne? Nadal nie rozumiem, jaki jest problem dla Chrome, aby wesprzeć to działanie! Jest to przydatne w niektórych sytuacjach, takich jak Canvas Fields, gdzie trzeba przetestować różne wejścia klawiatury. – GensaGames

+0

Protokół znacznie się zmienił między Selenium 2 i 3, szczególnie w przypadku powiązanych działań. Możesz znaleźć te informacje, czytając starą i nową specyfikację. Nie wiem, dlaczego Chrome nie przeniósł się do nowego interfejsu API. Może to być kwestia zasobów/budżetu. –