2017-06-10 39 views
6

Mam fragment kodu w robotach pythonowych, które działały. Zainstalowałem go na nowym systemie i próbuję teraz uzyskać właściwe zależności. Podczas korzystania geckodriver 0.13.0 i wykonanie następującego kodu:Problem Selenium i Geckodriver z tworzeniem webdrivera w Pythonie

 def login(self): 
      print self.colors.OKBLUE + "Logging into my site as User: " + self.config.email + self.colors.ENDC 
      username = self.driver.find_element_by_css_selector('.my_user_field') 
      for c in self.config.email: 
        print "Sending key: " + c 
        username.send_keys(c + "") 

pojawia się następujący błąd:

Sending key: b 
Traceback (most recent call last): 
    File "main.py", line 20, in <module> 
    crawler.start() 
    File "/home/tyrick/dev/pycrawlers/sc/src/main/python/new.py", line 39, in start 
    self.login() 
    File "/home/tyrick/dev/pycrawlers/sc/src/main/python/new.py", line 147, in login 
username.send_keys(c) 
    File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webelement.py", line 349, in send_keys 
    'value': keys_to_typing(value)}) 
    File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webelement.py", line 493, in _execute 
    return self._parent.execute(command, params) 
    File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 256, in execute 
    self.error_handler.check_response(response) 
    File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/errorhandler.py", line 194, in check_response 
    raise exception_class(message, screen, stacktrace) 
selenium.common.exceptions.WebDriverException: Message: Expected [object Undefined] undefined to be a string 

czytałem w kilku miejscach, że geckodriver ma błąd z tym, i powinno się używać 0.16.0. Więc próbowałem to równie dobrze jak 0.17.0, ale jestem teraz otrzymuję następujący błąd:

Traceback (most recent call last): 
    File "main.py", line 18, in <module> 
    crawler = New() 
    File "/home/tyrick/dev/pycrawlers/sc/src/main/python/new.py", line 28, in __init__ 
    self.driver = webdriver.Firefox() 
    File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/firefox/webdriver.py", line 152, in __init__ 
keep_alive=True) 
    File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 98, in __init__ 
    self.start_session(desired_capabilities, browser_profile) 
    File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 188, in start_session 
    response = self.execute(Command.NEW_SESSION, parameters) 
    File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 256, in execute 
    self.error_handler.check_response(response) 
    File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/errorhandler.py", line 194, in check_response 
    raise exception_class(message, screen, stacktrace) 
selenium.common.exceptions.WebDriverException: Message: elementScrollBehavior was not a the name of a known capability or a valid extension capability 

To tak, jakbym teraz nie może nawet zainicjować sterownika. Używam Selenium 3.4.3, co z tego, co przeczytałem, jest w porządku.

Jeśli ktokolwiek może mnie poprowadzić w kierunku rozwiązania, byłbym bardzo wdzięczny! Dzięki

+0

Hej Tyrick! Nadal chcesz rozwiązać ten problem? Czy zapoznałeś się z moją sugestią i prośbą? Twoje zdrowie! – iamdanchiv

Odpowiedz

5

Masz rację, masz dwa różne problemy.

Issue with geckodriver 0.13.0 :

Jest to najprawdopodobniej ponieważ c jest undefined.

Musisz zweryfikować/potwierdzić, że w rzeczywistości self.config.email zwraca prawidłowy ciąg (e-mail). Tak więc sprawdź, czy c zawiera oczekiwany e-mail przed wydaniem polecenia .send_keys().

Kolejnym ulepszeniem, o którym warto wspomnieć, jest brak bezpieczeństwa, jeśli chodzi o znalezienie pola nazwy użytkownika. Powinieneś użyć wyraźnego oczekiwania !

# Library imports 
from selenium.webdriver.common.by import By 
from selenium.webdriver.support.ui import WebDriverWait 
from selenium.webdriver.support import expected_conditions as EC 

# (...) 

def login(self): 
    print self.colors.OKBLUE + "Logging into my site as User: " + 
    self.config.email + self.colors.ENDC 

    # Polls the DOM for 3 seconds trying to find '.my_user_field' 
    username = WebDriverWait(self.driver, 3).until(EC.presence_of_element_located((By.CSS_SELECTOR, '.my_user_field'))) 

    for c in self.config.email: 

     # Validate 'c' is of type string 
     if (str(type(c)).find('str') != -1): 
      print "Sending key: " + c 
      username.send_keys(c + "") 
     else: 
      print "'c' is not what it used to be!" 

Wreszcie dodać cały fragment bo wygląda jakbyś rowerze przez listę e-maili i wysyłając je w polu nazwy użytkownika znalezionego wcześniej.

Issue with geckodriver 0.16.0 :

ta zawodzi, bo masz problem ze swoim instancji Kierowca: self.driver = webdriver.Firefox().

Proszę zaktualizować pytanie za pomocą pełnego fragmentu deklaracji sterownika (w tym możliwości profili &, jeśli takie istnieją). W przeciwnym razie trudno jest ustalić przyczynę błędu.

+0

Okazuje się, że "c" zawiera prawidłowy ciąg wiadomości e-mail. Możesz nawet zobaczyć na powyższym wydruku: "Wysyłanie klucza: b", gdzie "b" jest pierwszą postacią mojego e-maila. Myślę, że spróbuję sterownika Chrome i skontaktuję się z Tobą. – Tyrick

+0

Sure @Tyrick! Daj mi znać, jak poszło. Twoje zdrowie! – iamdanchiv

+0

Ten problem jest spowodowany błędem z ostatnią wersją firefox (53 i wyżej), sprawdź moją odpowiedź, ten problem został już naprawiony i nie pojawi się w następnej wersji checkodriver. – SEDaradji

1

To faktycznie nie ma nic wspólnego z kodem, jest to błąd z najnowszej wersji Firefoksa sprawdzić ten issue thread na repozytorium Geckodriver, trzeba będzie:

  • Downgrade do Firefox 52.0.
  • Poczekaj na kolejne wydanie Geckodriver.
  • Pobierz i skompiluj Geckodriver ręcznie.
  • pomocą drugiego kierowcy jak Chrome driver

najlepszym rozwiązaniem moim zdaniem jest pierwsza, będzie trzeba także wyłączyć automatyczne aktualizacje po downgrade aby zapobiec Firefox z wracając do najnowszej wersji (Ustawienia-> Zaawansowane -> update> Nigdy nie sprawdzaj dostępność aktualizacji)

1

Oto odpowiedź na twoje pytanie:

  • Zgodnie kwestia pozycji rozumiem, że problem zaczyna Mozilla Firefox przez GeckoDriver.
  • Jak wspomniałem wersję Selenium jako 3.4.3, można rozważyć użycie dowolnego z następującym obu geckodriver v0.16.0 lub v0.16.1 lub v0.17.0
  • Zgodnie swojej najnowszej stosu błędu śledzenia głównym problemem jest konfigurowanie instancji WebDriver.
  • Należy zauważyć, że obecne powiązanie Selenium-Python jest niestabilne w geckodriver i wygląda na specyficzne dla architektury. Tutaj znajdziesz github discussion i merge. Więc można dodatkowo zdać bezwzględną ścieżkę do pliku binarnego firefox jak firefox_binary argumentu podczas inicjowania webdriver

  • Oto zestaw roboczy bloku kodu przy użyciu Selenium wersję 3.4.3, geckodriver v0.17.0 & Mozilla Firefox 53.0 przez Python 3.6.1, który otwiera URL http://www.python.org:

    from selenium import webdriver 
    from selenium.webdriver.firefox.firefox_binary import FirefoxBinary 
    
    if __name__ == '__main__': 
    
        binary = FirefoxBinary('C:\\Program Files\\Mozilla Firefox\\firefox.exe') 
        driver = webdriver.Firefox(firefox_binary=binary,executable_path="C:\\Utility\\BrowserDrivers\\geckodriver.exe") 
        driver.get("http://www.python.org") 
    

Daj mi znać, jeśli to odpowiedzi na swoje pytania.

+1

Nie należy się tym zajmować, ale czy od początku do końca czytasz/śledzisz jego ślady błędów? :) Jego pierwszy numer ('0.16.0') to ** 100% ** problem' .send_keys() ', a drugi (' 0.17.0') ma inny błąd niż ten, na który wskazywałeś (co oznacza ** [this] (https://github.com/SeleniumHQ/selenium/issues/3884) **): AFAIK, "selenium.common.exceptions.WebDriverException: Message: Nie można znaleźć pasującego zestawu funkcji" jest inny from "selenium.common.exceptions.WebDriverException: Message: elementScrollBehavior nie było nazwą znanej możliwości ani prawidłowego rozszerzenia" – iamdanchiv

+0

Określenie ścieżki bezwzględnej nie pomogło. Wystąpił błąd z: "selenium.common.exceptions.WebDriverException: Message: elementScrollBehavior nie był nazwą znanej możliwości lub poprawnej możliwości rozszerzenia" – Tyrick

+0

@Tyrick My Answer nie ma nic wspólnego z 'elementemScrollBehavior'. Moja odpowiedź dotyczy nagłówka pytania dotyczącego problemu Selenium/geckodriver. Dzięki – DebanjanB

1

Nie mam wystarczająco dużo reputacji, aby dodać komentarz, ale w odniesieniu do odpowiedzi @ iamdanchiva, co "brak bezpieczeństwa, jeśli chodzi o znalezienie pola nazwy użytkownika. Powinieneś użyć wyraźnego oczekiwania!" Czy masz na myśli to, że nie ma bezpieczeństwa pod względem wywoływania błędu?

+0

Miałem na myśli, że ma on punkt słabości w niezabezpieczonej instrukcji '.find_element_by_css_selector()'. Ponieważ strony internetowe są powiązane z czasami odpowiedzi serwera WWW, ** najlepszą praktyką ** jest czekanie na każdy element przez co najmniej kilka sekund (o ile nie używasz niejawnych czekania). W przeciwnym razie otrzymasz niestabilne testy funkcjonalne ... które w zasadzie są # @ *, ponieważ nie możesz im ufać na tyle, aby używać ich również do wdrażania kompilacji. – iamdanchiv

+0

A przez wyraźne oczekiwanie masz na myśli coś takiego jak time.sleep()? –

+1

Nie, 'time.sleep()' i powiązane polecenia nie powinny być nigdy używane poza zakresem debugowania. Wyraźne oczekiwanie będzie odpytywać DOM (zwykle co 250 lub 500 ms, w zależności od frameworka) przez podany czas. Zwróci wyjątek 'WebElement' lub' NoSuchElement'. Sprawdź ** [Dokumentacja StackOverflow SeleniumWebdriver - Waits] (https://stackoverflow.com/documentation/selenium-webdriver/4435/wait#t=201706191154328390365) ** lub ** [oficjalna dokumentacja] (http: // www .seleniumhq.org/docs/04_webdriver_advanced.jsp) **, gdzie ulegają awarii czekając na 'WebElements'. Mam nadzieję, że to pomoże! – iamdanchiv