2012-09-12 34 views
9

Ich versuche, eine Verwaltungsaufgabe zu automatisieren, bis jetzt habe ich Selen gemacht, um auf ein Element klicken, um ein Dropdown-Menü anzuzeigen.Klicken Sie auf ein Dropdown-Menü mit Selenium Webdriver

enter image description here

Wenn es die Zeit auf einer dieser Menüelemente zu klicken kommt ich einen Fehler haben zu sagen, dass das Element angezeigt werden muss.

Code:

driver = webdriver.Chrome() 
driver.implicitly_wait(10) 
driver.get(url) 
doc = driver.find_element_by_css_selector('td.ms-vb-title > table') 
try: 
    doc.click() 
    time.sleep(4) 
    menu = driver.find_element_by_xpath('//menu/span[5]') 
    time.sleep(4) 
    print dir(menu) 
    menu.click() 
except: 
    traceback.print_exc() 
    driver.quit() 

Fehler:

Traceback (most recent call last): 
    File "aprobar_docs.py", line 22, in main 
    menu.click() 
    File "C:\Python27\lib\site-packages\selenium\webdriver\remote\webelement.py", 
line 52, in click 
    self._execute(Command.CLICK_ELEMENT) 
    File "C:\Python27\lib\site-packages\selenium\webdriver\remote\webelement.py", 
line 205, in _execute 
    return self._parent.execute(command, params) 
    File "C:\Python27\lib\site-packages\selenium\webdriver\remote\webdriver.py", l 
ine 156, in execute 
    self.error_handler.check_response(response) 
    File "C:\Python27\lib\site-packages\selenium\webdriver\remote\errorhandler.py" 
, line 147, in check_response 
    raise exception_class(message, screen, stacktrace) 
ElementNotVisibleException: Message: u'Element must be displayed to click' 

Wie Sie den Code viel sehen wartet das Element geladen werden. Ich habe auch versucht, die is_displayed Eigenschaft des Elements zu True zu setzen, aber funktionierte auch nicht.

Hinweis: das Element, das nicht angezeigt ist, ist die auf der XPath-Suche, es vorhanden ist, weil ich es mit dir (Menü) angemeldet haben

Edit:

Die menu Variable nicht ist Das Menü selbst ist eine der Bereiche, die Elemente des Menüs sind, doc ist das Perfil HTML-Element, auf das geklickt wird, um das Dropdown anzuzeigen.

Edit 2:

das DOM auf Chrom-Tools Inspizieren, wenn Sie ein doc ein neues Menü auf dem Baum erstellt wird, klicken Sie auf, ich weiß nicht, ob es wegen eines Ajax-Aufruf oder Vanille-js ist, Ich denke nicht, dass es wirklich so wichtig ist, wie es erschaffen wurde. Ich kann es nicht von der Seite abrufen und daraus ein Python-Objekt machen, das zumindest nicht im Code angezeigt wird.

Finale Edit:

Ich landete einige JavaScript ausgeführt wird, damit es funktioniert. Anscheinend, wenn Selenium den Menüeintrag findet, verliert das erste Element, das die Menüauswahl auslöst, den Fokus und es macht das Menü wieder unsichtbar. Wenn Sie einen Menüeintrag nicht auswählen und einige Zeit warten, wird das Menü-Dropdown immer angezeigt versuchen Sie, ein Element aus dem Menü zu wählen, das Menü verschwindet.

+1

Warum schläfst du auf beiden Seiten der 'menu' Element-Lookup?Wenn das Element beim Abrufen des Seitenelements nicht sichtbar ist, kann Webdriver es nicht anklicken, unabhängig davon, wie lange Sie warten. –

+0

@ sr2222 Die Seite wird abgerufen, wenn Sie driver.get() aufrufen, das Dropdown wird auf dem Bildschirm angezeigt und ist in der Dom-Struktur vorhanden, wenn Sie doc.click() ausführen, ich habe die Möglichkeit, dass das Dropdown-Menü nicht geladen wird, eliminiert so schnell wie Code ausgeführt wird. Das Menüelement ist vorhanden und sichtbar, zumindest für den Menschen, das kann ich garantieren. – loki

+0

Versuchen Sie, 'doc' erneut zu entfernen, nachdem Sie auf geklickt und darauf gewartet haben, dass das Menü angezeigt wird, und vergleichen Sie das Attribut 'id' der Objekte davor und danach. Ich habe den schleichenden Verdacht, dass der Selenserver tatsächlich auf ein zwischengespeichertes Webelementobjekt bei der Extraktion des zweiten Elements verweist (da Ihre Klickaktion kein Seitenladeereignis auslöst, wird das Seitenobjekt nicht veraltet). –

Antwort

8

Warum Sie eine Option nicht wählen wie diese

el = driver.find_element_by_id('id_of_select') 
for option in el.find_elements_by_tag_name('option'): 
    if option.text == 'The Options I Am Looking For': 
     option.click() # select() in earlier versions of webdriver 

Wenn Sie hier klicken, Ihre Liste zu füllen ist nicht einen Ajax-Aufruf Brennen, brauchen Sie eigentlich nicht den Klick auszuführen.

+0

@Nllesh Sharma Ich habe diesen Ansatz verwendet, aber ich bekomme einen Fehler, dass Web-Element-Objekt nicht iterierbar ist. Wie wiederholst du es in der for-Schleife, wenn es nicht iterierbar ist – abhi

+0

@abhi bist du sicher mit find_elementSSSSS_by_tag_name()? (um sicher zu gehen, dass du das gesehen hast) –

0

Sie müssen den Link des Ziels finden. Sie nicht wirklich klicken Sie auf Elemente, klicken Sie auf Links ... (oder vielmehr, klicken Sie auf Elemente mit Links in ihnen). Davon abgesehen ist der sicherste Weg, auf einen Link zu klicken, das Link-Element zu isolieren.

frame = driver.find_element_by_id('this_is_your_frame_name') 
links = frame.find_elements_by_xpath('.//a') 
links[1].click() 

oder alternativ

for link in links: 
    if link.text() == "Administratar Permisos": 
     link.click() 
Verwandte Themen