2016-01-24 13 views
10

Muszę przejrzeć wszystkie strony na mojej stronie. W lewym górnym rogu znajduje się rozwijane okno z wszystkimi dostępnymi miastami. Chcę odwiedzić każdą stronę, wybierając każdą pozycję w tym polu rozwijanym. Pole rozwijane ma pasek przewijania, i kiedy chcę, aby wybrać opcję, która jest pod nim, to daje mi komunikat wyjątek:Element jest obecnie niewidoczny, więc nie można nim wchodzić w interakcję z rozwijanym polem Selenium Python

Message: Element is not currently visible and so may not be interacted with 
Stacktrace: 
    at fxdriver.preconditions.visible (file:///tmp/tmpHWLMyH/extensions/[email protected]/components/command-processor.js:9981) 
    at DelayedCommand.prototype.checkPreconditions_ (file:///tmp/tmpHWLMyH/extensions/[email protected]/components/command-processor.js:12517) 
    at DelayedCommand.prototype.executeInternal_/h (file:///tmp/tmpHWLMyH/extensions/[email protected]/components/command-processor.js:12534) 
    at DelayedCommand.prototype.executeInternal_ (file:///tmp/tmpHWLMyH/extensions/[email protected]/components/command-processor.js:12539) 
    at DelayedCommand.prototype.execute/< (file:///tmp/tmpHWLMyH/extensions/[email protected]/components/command-processor.js:12481) 

Herezje kod:

#!/bin/env/python 
# -*- coding: utf-8 -*- 

import time 
from selenium.webdriver.common.by import By 
from selenium.webdriver.support.wait import WebDriverWait 
from selenium import webdriver 
from selenium.common.exceptions import NoSuchElementException 
from selenium.webdriver.support import expected_conditions as EC 
from selenium.webdriver.common.by import By 
from selenium.webdriver.support.ui import Select 

def get_browser(): 
    return webdriver.Firefox() 


main_page_url = "http://example.com/" 
basic_url = 'http://example.com/ogloszenia-kobiet.html' 

def get_city_list(url) : 

    AGE_ACCEPT_BUTTON_XPATH = ".//*[@id='columns']/div/div[2]/section/div/div/div/div/div/div[2]/div[2]/a[2]" 
    COMBOBOX_XPATH = ".//*[@id='select_city']/li/form/div/button" 
    COMBOBOX_OPTION_XPATH = ".//*[@id='select_city']/li/form/div/div/ul/li[%s]/a/span[1]" 
    CHOOSE_BUTTON_XPATH = ".//*[@id='select_city']/li/form/button" 

    pages = [] 

    try: 
     browser = get_browser() 
     wait = WebDriverWait(browser, 100) 
     browser.get(main_page_url) 
     time.sleep(2) 

     button_age_accept = browser.find_element_by_xpath(AGE_ACCEPT_BUTTON_XPATH) 
     button_age_accept.click() 
     time.sleep(10) 

     browser.get(url) 

     i = 2 

     while(True) : 
      try : 

       button_combobox = browser.find_element_by_xpath(COMBOBOX_XPATH) 
       button_combobox.click() 
       time.sleep(5) 

       element_xpath = COMBOBOX_OPTION_XPATH % i 
       option_in_combobox = browser.find_element_by_xpath(element_xpath) 
       # wait.until(EC.invisibility_of_element_located((By.XPATH, element_xpath))) 
       # option_in_combobox = WebDriverWait(browser, 10).until(lambda browser : browser.find_element_by_xpath(element_xpath)) 
       option_in_combobox.click() 
       time.sleep(5) 

       button_choose = browser.find_element_by_xpath(CHOOSE_BUTTON_XPATH) 
       button_choose.click() 
       time.sleep(5) 

       pages.append(browser.current_url) 

       i += 1 
      except Exception, e: 
       print e 
       break 

     browser.close() 
     return pages 

    except Exception, e: 
     info = 'Generic exception\n' 
     print e 
     return [] 

get_city_list(basic_url) 

Próbowałem też z paska przewijania , próbował go przesunąć w dół, ale nadal, bez efektu. mogę przejść tylko te strony, które są na szczycie tej listy rozwijanej:

#!/bin/env/python 
# -*- coding: utf-8 -*- 

import time 
from selenium.webdriver.common.by import By 
from selenium.webdriver.support.wait import WebDriverWait 
from selenium import webdriver 
from selenium.webdriver.common.action_chains import ActionChains 
from selenium.common.exceptions import NoSuchElementException 
from selenium.webdriver.support import expected_conditions as EC 
from selenium.webdriver.common.by import By 
from selenium.webdriver.support.ui import Select 

def get_browser(): 
    return webdriver.Chrome() 


main_page_url = "http://example.com/" 
basic_url = 'http://example.com/ogloszenia-kobiet.html' 

def get_city_list(url) : 

    AGE_ACCEPT_BUTTON_XPATH = ".//*[@id='columns']/div/div[2]/section/div/div/div/div/div/div[2]/div[2]/a[2]" 
    COMBOBOX_XPATH = ".//*[@id='select_city']/li/form/div/button" 
    COMBOBOX_OPTION_XPATH = ".//*[@id='select_city']/li/form/div/div/ul/li[%s]/a/span[1]" 
    CHOOSE_BUTTON_XPATH = ".//*[@id='select_city']/li/form/button" 

    pages = [] 

    try: 
     browser = get_browser() 
     wait = WebDriverWait(browser, 100) 
     browser.get(main_page_url) 
     time.sleep(2) 

     button_age_accept = browser.find_element_by_xpath(AGE_ACCEPT_BUTTON_XPATH) 
     button_age_accept.click() 
     time.sleep(10) 

     browser.get(url) 

     i = 2 

     while(True) : 
      try : 

       button_combobox = browser.find_element_by_xpath(COMBOBOX_XPATH) 
       button_combobox.click() 
       time.sleep(5) 

       element_xpath = COMBOBOX_OPTION_XPATH % i 
       option_in_combobox = browser.find_element_by_xpath(element_xpath) 

       actionChains = ActionChains(browser) 
       scrollbar = browser.find_element_by_xpath("/html/body/section/section[2]/div/div[2]/section/div/div/div/div[1]/ul/li/form/div/div/ul") 
       actionChains.click_and_hold(scrollbar).perform() 
       actionChains.move_by_offset(0,10+i).perform() 
       actionChains.release() 

       browser.execute_script("arguments[0].scrollIntoView();", option_in_combobox) 
       option_in_combobox.click() 

       browser.execute_script("window.scrollTo(0, 0);") 

       button_choose = browser.find_element_by_xpath(CHOOSE_BUTTON_XPATH) 
       button_choose.click() 
       time.sleep(5) 

       pages.append(browser.current_url) 

       i += 1 
      except Exception, e: 
       print e 
       break 

     browser.close() 
     return pages 

    except Exception, e: 
     info = 'Generic exception\n' 
     print e 
     return [] 

pages = get_city_list(basic_url) 
for p in pages : 
    with open('links.txt', 'a') as the_file: 
     the_file.write(p) 
     the_file.write('\n') 

------------------------- -------------------------------------------------- -------------------------------------------------- ------- UPDATE: --------------------------------- -------------------------------------------------- -------------------------------------------------

Na razie jestem przy użyciu Kubuntu 14.04. Mam Python 2.7.11 i Selenium 2.49.2. Mój bieżący kod:

#!/bin/env/python 
# -*- coding: utf-8 -*- 

import time 
from selenium.webdriver.common.by import By 
from selenium.webdriver.support.wait import WebDriverWait 
from selenium import webdriver 
from selenium.webdriver.common.action_chains import ActionChains 
from selenium.common.exceptions import NoSuchElementException 
from selenium.webdriver.support import expected_conditions as EC 
from selenium.webdriver.common.by import By 
from selenium.webdriver.support.ui import Select 

# def get_browser(): 
#  options = webdriver.ChromeOptions() 
#  options.add_argument("--start-maximized") 
#  return webdriver.Chrome(chrome_options=options) 


def get_browser(): 
    return webdriver.Firefox() 

main_page_url = "http://example.com/" 
basic_url = 'http://example.com/ogloszenia-kobiet.html' 

def get_city_list(url) : 

    AGE_ACCEPT_BUTTON_XPATH = ".//*[@id='columns']/div/div[2]/section/div/div/div/div/div/div[2]/div[2]/a[2]" 
    COMBOBOX_XPATH = ".//*[@id='select_city']/li/form/div/button" 
    COMBOBOX_OPTION_XPATH = ".//*[@id='select_city']/li/form/div/div/ul/li[%s]/a/span[1]" 
    CHOOSE_BUTTON_XPATH = ".//*[@id='select_city']/li/form/button" 

    pages = [] 

    try: 
     browser = get_browser() 
     wait = WebDriverWait(browser, 100) 
     browser.get(main_page_url) 
     time.sleep(2) 

     button_age_accept = browser.find_element_by_xpath(AGE_ACCEPT_BUTTON_XPATH) 
     button_age_accept.click() 
     time.sleep(10) 

     browser.get(url) 

     i = 2 

     while(True) : 
      try : 

       button_combobox = browser.find_element_by_xpath(COMBOBOX_XPATH) 
       button_combobox.click() 
       time.sleep(5) 

       element_xpath = COMBOBOX_OPTION_XPATH % i 
       option_in_combobox = browser.find_element_by_xpath(element_xpath) 
       option_in_combobox.click() 

       button_choose = browser.find_element_by_xpath(CHOOSE_BUTTON_XPATH) 
       button_choose.click() 
       time.sleep(5) 

       pages.append(browser.current_url) 

       i += 1 
      except Exception, e: 
       print e 
       break 

     browser.close() 
     return pages 

    except Exception, e: 
     info = 'Generic exception\n' 
     print e 
     return [] 

pages = get_city_list(basic_url) 
for p in pages : 
    with open('links.txt', 'a') as the_file: 
     the_file.write(p) 
     the_file.write('\n') 

Dla Firefox, kod wychodzi na element „Gdańsk” z komunikatem: string indices must be integers, więc to oznacza, że ​​nie może znaleźć każdy element mojego combobox.

W Chrome i Windows XP wychodzi z "Bielska-Białej", co oznacza, że ​​nie znajduje każdego elementu w moim comboboxie. ...

Jak mogę rozwiązać ten problem?

+1

pamiętać, że ta strona ma użytkowników w wieku 13, a także specjalistów z dostępem do witryny z pracy, proszę nie odwołuje się do stron zawierających nagość w swoim pytaniu . Umieść wystarczającą ilość szczegółów w samym pytaniu, aby na to pytanie odpowiedzieć. – josliber

Odpowiedz

4

Albo przejść do elementu, a następnie kliknij:

from selenium.webdriver.common.action_chains import ActionChains 

actions = ActionChains(browser) 
actions.move_to_element(option_in_combobox).click().perform() 

lub scroll into it's view:

browser.execute_script("arguments[0].scrollIntoView();", option_in_combobox) 

lub kliknąć element via javascript:

browser.execute_script("arguments[0].click();", option_in_combobox) 

Dla przeglądarki Firefox kod wychodzi z elementu "Gdańsk" z komunikatem: wskaźniki łańcuchowe muszą być liczbami całkowitymi, a więc oznacza to, że nie znajdują każdego elementu w moim bloku combobox.

Wystąpił problem z selenem 2.49, który może powodować ten błąd TypeError. Musisz zmienić wersję na 2.48:

pip install selenium==2.48 
+0

Po pierwsze: dziękuję za odpowiedź. Po drugie: zmodyfikowałem mój kod, tak jak sugerowałeś, i 1) twoje drugie podejście (ten kod: https://gist.github.com/anonymous/00789e9cc3c13fc6477c) daje mi "Element nie jest klikalny w punkcie ..." i robi nie znajduję wszystkich linków, których potrzebuję, tylko niektóre z nich 2) twoje pierwsze podejście (mój kod: https://gist.github.com/anonymous/880841d0166943133a42) daje "element niewidoczny" i nie znajduje żadnych linków 3) twoje trzecie podejście (mój kod: https://gist.github.com/anonymous/6261a924b4f15760742f) również daje "element niewidoczny" i wszelkie linki są zapisywane ... jakieś pomysły? – Katie

+0

@Katie, proszę najpierw wypróbować odpowiedź Cyryla i zobaczyć, czy to pomaga. Sprawdźmy, czy problem nadal istnieje. Dzięki. – alecxe

+0

Niestety, to nie zadziałało – Katie

3

Jak wspomniano należy najpierw przejść do elementu opcji przed kliknięcie na niego: actions.move_to_element(option_in_combobox).click().perform(). Teraz element "button_choose" jest niewidoczny, ponieważ przeglądarka przewinęła się w dół. Aby to naprawić, musisz przewinąć do góry, a następnie kliknąć przycisk:

browser.execute_script("window.scrollTo(0, 0);") # scroll to top 

button_choose = browser.find_element_by_xpath(CHOOSE_BUTTON_XPATH) 
button_choose.click() 
+0

To również nie działa. Mój kod: http://codepad.org/Utw8X1Dw pobiera tylko niektóre z dostępnych łączy, nie wszystkie. Wygląda na to, że nadal ma problem z przewijaniem do miast znajdujących się u dołu tego rozwijanego okna. – Katie

+0

Twój kod działa dla mnie. Ustawiłem na 40 i działało dla wszystkich miast na dole (w tym "zielona-gora"). Uwaga: musiałem zmaksymalizować Chrome, aby działało, a Firefox działał po wyjęciu z pudełka. – Cyril

+0

To jest naprawdę dziwne. Wypróbowałem mój kod zarówno na Kubuntu, jak i na Windowsie i mam te same błędy, przykładowe błędy dla kodu, który napisałem (testowałem na Windows): https://gist.github.com/anonymous/8a6d50228ac12cc4cc72, https://gist.github.com/anonymous/eac439ef03ce9509e776, zmodyfikowany kod: https://gist.github.com/anonymous/a0fc50801436948bbf5c – Katie

3

Próbowałem w Javie i działa bardzo dobrze. Proszę, popatrz na pętlę głównie, ponieważ tutaj jestem w stanie wybrać opcje jeden po drugim. Właśnie użyłem Thread.sleep, ponieważ wiem, że możemy również używać czekania. Aby zrobić podobne do pytania, które właśnie dodałem do StringBuffer tutaj, wiem, że możemy dodać do każdego kolektora w java. Ja nie następuje dokładnie tak, jak przyjmowanie wiek itd jak powiedziałem, że koncentruje się na tej rozwijanej wyboru ..

public class Dog { 

    private WebDriver driver; 
    private String baseUrl; 
    private StringBuffer verificationErrors = new StringBuffer(); 

    @BeforeClass() 
    public void setUp() throws Exception { 
    // driver = new FirefoxDriver(); 
     System.setProperty("webdriver.chrome.driver", "E:\\selenium_setups\\chromedriver_win32\\chromedriver.exe"); 
     driver=new ChromeDriver(); 
    driver.manage().window().maximize(); 
    baseUrl = "http://example.com/"; 
    driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS); 
    } 

    @Test 
    public void testStackoverflowIssue() throws Exception { 

    driver.get(baseUrl); 
    driver.findElement(By.cssSelector(".btn.btn-success")).click(); 
    driver.get("http://example.com/ogloszenia-kobiet.html"); 
    List<WebElement> options=driver.findElements(By.xpath(".//*[@id='select_city']/li/form/div/div/ul/li")); 

    for(int i=1; i<=options.size(); i++){ 

    driver.findElement(By.xpath("(//button[@type='button'])[4]")).click(); 
    driver.findElement(By.xpath("//ul[@id='select_city']/li/form/div/div/ul/li["+i+"]")).click(); 
    driver.findElement(By.cssSelector("button.btn.btn-success")).click(); 
    Thread.sleep(5000); 
    verificationErrors.append(driver.getCurrentUrl()); 
    System.out.println(driver.getCurrentUrl() +" >>> iteration " +i); 
    driver.navigate().to("http://example.com/ogloszenia-kobiet.html"); 
    Thread.sleep(5000); 
    } 
    } 

}

Mam nadzieję, że pomaga w Pythonie, aby wybrać rozwijanej wartości ..

wyjście enter image description here

Dziękuję, Murali

+0

Dziękuję. Zredagowałem do 'Selenium 2.48', jak zasugerował @alecxe, i zmodyfikowałem twój kod (faktycznie przetłumaczony na Python), ale problem pozostaje ten sam. Mój kod dostaje tylko widoczną część rozwijanego okna, jednak kiedy zmaksymalizuję okno przeglądarki w Firefoksie, daje mi to więcej linków niż poprzednie podejścia (do "Krakowa"). Ale potem, po osiągnięciu "Krakowa", program się kończy, a nie można uzyskać elementów z dołu rozwijanego okna. Mój zmodyfikowany kod jest tutaj: https://gist.github.com/anonymous/9cb82acf839d6b92731d – Katie

+0

Ponieważ muszę zbudować plik wykonywalny Windows z tym kodem, wypróbowałem go także w Windows XP i Chrome. Tam problem jest dokładny jak wcześniej. Twój kod może docierać tylko do "Bielsko-Białej" i kończy się, mówiąc, że 'Element nie jest klikalny w punkcie (1018, 508)' ... Huh – Katie

+0

@Katie, zmieniono chromedriver. jego działało bardzo dobrze widzisz obraz wyjściowy. Użyłem tego xpath // ul [@ id = 'select_city']/li/form/div/div/ul/li ["+ ​​i +"], aby wybrać wartości z rozwijanego menu. nie jestem wykorzystany do rozpiętości. mam nadzieję, że jesteś zauważony. dzięki –

3

spróbować tego przed wyborem „Obecnie invisi Element ble”, a po kliknięciu w rozwijane menu:

browser.execute_script("document.getElementsByClassName('dropdown-menu inner selectpicker')[0].setAttribute('style', '');") 
Powiązane problemy