2015-05-17 20 views
12

Quello che sto cercando di realizzareSelenio: Il tentativo di login con i biscotti - "possibile impostare solo i cookie per il dominio corrente"

Sto cercando di accedere a un sito web in cui i cookie devono essere abilitati utilizzando Selenio senza testa , Sto usando PhantomJS per il driver.

Problema

ho registrato la procedura utilizzando Selenium IDE dove funziona bene con Firefox (non senza testa). Quindi ho esportato il codice in Python e ora non riesco ad accedere perché genera un errore che dice "Può solo impostare cookie per il dominio corrente". Non so perché sto riscontrando questo problema, non sono nel dominio corretto?

Codice

from selenium import webdriver 
from selenium.webdriver.common.by import By 
from selenium.webdriver.common.keys import Keys 
from selenium.webdriver.support.ui import Select 
import unittest, time, re 

     self.driver = webdriver.PhantomJS() 
     self.driver.implicitly_wait(30) 
     self.base_url = "https://login.example.com" 

     driver = self.driver 
     driver.get(self.base_url) 

     all_cookies = self.driver.get_cookies() 

     # It prints out all cookies and values just fine 
     for cookie in all_cookies 
      print cookie['name'] + " --> " + cookies['value'] 

     # Set cookies to driver 
     for s_cookie in all_cookies: 
      c = { s_cookie['name'] : s_cookie['value']} 
      # This is where it's throwing an error saying "Can only set Cookies for current domain 
      driver.add_cookie(c) 

     ... 

Quello che ho provato

Ho provato il salvataggio dei cookie in un dizionario, andare in un altro dominio, risalente al dominio originale e aggiunto i biscotti e quindi prova ad accedere ma ancora non funziona (come suggerito in this thread)

Qualsiasi aiuto è apprezzato.

+0

Se si sta cercando di accedere a una pagina, poi lasciare il sito e andare in un altro sito, effettuare il login lì, e quindi tornare al sito 1, sarei molto tentato di forzare nuovamente l'accesso con il tuo script. Suggerirei anche di avviare 2 driver, uno per il sito A e uno per il sito B. 'driver1 = webdriver.PhandomJS()' & 'driver2 = webdriver.PhantomJS()' – ntk4

risposta

5

Indagare su ciascuna coppia di cookie. Mi sono imbattuto in problemi simili e alcuni dei cookie appartenevano a Google. È necessario assicurarsi che i cookie vengano aggiunti solo al dominio corrente e appartengano allo stesso dominio. In tal caso è prevista la tua eccezione. Nota a margine, se lo ricordo correttamente non è possibile utilizzare localhost per aggiungere i cookie se lo si fa. Cambia in indirizzo IP. Inoltre, analizza i cookie che stai ricevendo specificatamente dominio e informazioni sulla scadenza. Vedi, se stanno tornando null

Modifica

Ho fatto questo semplice test su Gmail per mostrare quello che hai fatto di sbagliato. A prima vista non ho notato che stai cercando di prendere un cookie parziale, una coppia, e aggiungerlo al dominio. Poiché, il cookie non ha informazioni su Dominio, percorso, scadenza ecc., Stava tentando di aggiungere il cookie al dominio corrente (127.0.0.1) e di lanciare alcune informazioni fuorvianti che non avevano alcun senso. Nota: per essere un cookie valido, è necessario disporre del dominio e delle informazioni sulla scadenza corretti mancanti.

import unittest 
from selenium.webdriver.common.by import By 

from selenium import webdriver 


__author__ = 'Saifur' 


class CookieManagerTest(unittest.TestCase): 
    def setUp(self): 
     self.driver = webdriver.PhantomJS("E:\\working\\selenium.python\\selenium\\resources\\phantomjs.exe") 
     self.driver.get("https://accounts.google.com/ServiceLogin?service=mail&continue=https://mail.google.com/mail/") 
     self.driver.find_element(By.ID, "Email").send_keys("userid") 
     self.driver.find_element(By.ID, "next").click() 
     self.driver.find_element(By.ID, "Passwd").send_keys("supersimplepassword") 
     self.driver.find_element(By.CSS_SELECTOR, "[type='submit'][value='Sign in']").click() 
     self.driver.maximize_window() 

    def test(self): 
     driver = self.driver 
     listcookies = driver.get_cookies() 

     for s_cookie in listcookies: 
      # this is what you are doing 
      c = {s_cookie['name']: s_cookie['value']} 
      print("*****The partial cookie info you are doing*****\n") 
      print(c) 
      # Should be done 
      print("The Full Cookie including domain and expiry info\n") 
      print(s_cookie) 
      # driver.add_cookie(s_cookie) 


    def tearDown(self): 
     self.driver.quit() 

Console uscita:

D: \ Python34 \ python.exe "D: \ Program Files (x86) \ JetBrains \ PyCharm Educational Edition 1.0.1 \ aiutanti \ PyCharm \ utrunner.py "E: \ working \ selenium.python \ selenium \ python \ FirstTest.py :: CookieManagerTest true Test iniziato alle 9:59 AM ...

******* Le informazioni dei cookie parziale si sta facendo *******

{ 'PREF': 'ID = *******: FF = 0: LD = it: TM = *******: LM = *******: GM = 1: S = ******* '}

Il cookie completo incluso dominio e scadenza info

{'httponly': Falso, 'nome': '*******', 'valore': 'ID = *******: FF = 0: LD = it: TM = *******: LM = 1432393656: GM = 1: S = iNakWMI5h_2cqIYi ',' percorso ':'/',' espira ':' Lun, 22 May 2017 15:07:36 GMT ',' sicuro ": False," scadenza ": *******," dominio ":" .google.com "}

Avviso: Ho appena sostituito alcune informazioni con ******* apposta

+0

Penso che tu abbia ragione che sto aggiungendo i cookie da 'localhost', ma come faccio ad aggiungerli al driver dal dominio? I cookie contengono informazioni sul dominio, che sono '.example.com' e' example.com'. – simeg

+0

Dovresti usare i cookie e aggiungere cookie nello stesso dominio. E 'questo che stai chiedendo? – Saifur

+0

Guardando il mio codice - non è quello che sto facendo? Non vado in un altro dominio prima di aggiungere i cookie, ed è per questo che sono confuso. – simeg

1

Stavo per aggiungere solo un commento sul fondo di ciò che ha detto @Saifur sopra, ma ho pensato che non avevo abbastanza nuovi contenuti da giustificare un commento completo

La rivelazione per me, avendo esattamente lo stesso errore, è stata che l'utilizzo di Selenium funziona esattamente come se si stesse aprendo il browser e facendo clic e digitando fisicamente le cose. Con questo in mente, se si inserisce l'utente/passaggio in Selenium e si preme click(), il driver Selenium, in caso di autenticazione autenticata, avrà automaticamente il cookie in esso. Negando così ogni necessità di distruggere il mio cookie salvato (probabilmente sta per scadere presto). Mi sono sentito un po 'sciocco a rendermene conto. Ha reso tutto molto più semplice.

Utilizzando il codice di @ Saifur sopra come modello, ho apportato alcune modifiche e rimosso quello che ritengo un po 'eccessivo di un'intera classe extra per l'esecuzione in questo esempio.

url = 'http://domainname.com' 
url2 = 'http://domainname.com/page' 
USER = 'superAwesomeRobot' 
PASS = 'superSecretRobot' 

# initiates your browser 
driver = webdriver.PhantomJS() 
# browses to your desired URL 
driver.get(url)    
# searches for the user or email field on the page, and inputs USER 
driver.find_element_by_id("email").send_keys(USER) 
# searches for the password field on the page, and inputs PASS 
driver.find_element_by_id("pass").send_keys(PASS) 
# finds the login button and click you're in 
driver.find_element_by_id("loginbutton").click() 

da qui si può accedere alla pagina che si desidera affrontare

driver.get(url2) 

nota: se si dispone di un sito moderno che carichi auto quando si scorre verso il basso, potrebbe essere comodo da usare questo:

driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") 

Vorrei anche notare, @simeg, che selenio automaticamente si suppone di aspettare fino a quando la pagina è tornata che è caricato (e sì, mi Ho avuto il problema AJAX a cui ci si riferisce, quindi a volte è necessario attendere qualche secondo: quale pagina impiega più di 30 secondi per caricare ?!). Il modo in cui stai eseguendo il tuo comando di attesa è solo in attesa del caricamento di PhantomJS, non della stessa pagina, quindi non mi sembra utile considerando la funzione incorporata:

Il metodo driver.get navigerà a una pagina data dall'URL. WebDriver attenderà fino a quando la pagina non sarà completamente caricata (ovvero, l'evento "onload" è stato attivato) prima di restituire il controllo al test o allo script. Vale la pena notare che se la tua pagina utilizza molto AJAX in caricamento, WebDriver potrebbe non sapere quando è stato caricato completamente.

fonte: http://selenium-python.readthedocs.io/getting-started.html#example-explained

Spero che questo aiuti qualcuno!

1

Alcune pagine Web utilizzano troppe chiavi nei cookie non supportate dal webdriver, quindi si ottiene un "errorMessage": "Può solo impostare cookie per il dominio corrente", anche se si è sicuri al 100% che si stanno impostando i cookie per il dominio attuale. Un esempio di tale pagina Web è "https://stackoverflow.com/". In questo caso, è necessario assicurarsi che solo i tasti richiesti vengano aggiunti ai cookie, come menzionato in alcuni post precedenti.

driver.add_cookie({k: cookie[k] for k in ('name', 'value', 'domain', 'path', 'expiry') if k in cookie}) 

In constrast, alcune pagine web uso troppo pochi tasti nei cookies, che sono richiesti da WebDriver, allora si ottiene un "errorMessage": "è possibile impostare solo i cookie per il dominio corrente", dopo si fissa la prima problema. Un esempio di tale pagina Web è "https://github.com/". È necessario aggiungere la chiave "scadenza" ai cookie per questa pagina Web.

for k in ('name', 'value', 'domain', 'path', 'expiry'): 
     if k not in list(cookie.keys()): 
      if k == 'expiry': 
       cookie[k] = 1475825481 

tutti Mettendo insieme, il codice completo è il seguente:

# uncommented one of the following three URLs to test 
#targetURL = "http://pythonscraping.com" 
targetURL = "https://stackoverflow.com/" 
#targetURL = "https://github.com/" 

from selenium import webdriver 
driver = webdriver.PhantomJS() 
driver.get(targetURL) 
driver.implicitly_wait(1) 
#print(driver.get_cookies()) 

savedCookies = driver.get_cookies() 
driver2 = webdriver.PhantomJS() 
driver2.get(targetURL) 
driver2.implicitly_wait(1) 
driver2.delete_all_cookies() 

for cookie in savedCookies: 
    # fix the 2nd problem 
    for k in ('name', 'value', 'domain', 'path', 'expiry'): 
     if k not in list(cookie.keys()): 
      if k == 'expiry': 
       cookie[k] = 1475825481 
    # fix the 1st problem 
    driver2.add_cookie({k: cookie[k] for k in ('name', 'value', 'domain', 'path', 'expiry') if k in cookie})  
print(cookie) 

driver2.get(targetURL) 
driver2.implicitly_wait(1) 
Problemi correlati