Selenium: попытка входа в систему с файлами cookie - "Может устанавливать только файлы cookie для текущего домена" - программирование

Selenium: попытка входа в систему с файлами cookie - "Может устанавливать только файлы cookie для текущего домена"

То, что я пытаюсь достичь

Я пытаюсь войти на сайт, где файлы cookie должны быть включены с использованием Selenium без головы, я использую PhantomJS для драйвера.

Проблема

Сначала я записал процедуру с использованием Selenium IDE, где он отлично работает с использованием Firefox (не без головы). Затем я экспортировал код в Python, и теперь я не могу войти в систему, потому что он выдает сообщение об ошибке "Могу только установить Cookies для текущего домена". Я не знаю, почему я получаю эту проблему, разве я не в правильном домене?

код

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 throwing an error saying "Can only set Cookies for current domain
            driver.add_cookie(c)

        ...

Что я пробовал

Я попытался сохранить файлы cookie в dict, перейдя в другой домен, вернувшись в исходный домен и добавив файлы cookie, а затем попытаюсь войти в систему, но он все еще не работает (как предложено в этот поток)

Любая помощь приветствуется.

4b9b3361

Ответ 1

Исследуйте каждую пару файлов cookie. Я столкнулся с подобными проблемами, и некоторые из файлов cookie принадлежали Google. Вы должны убедиться, что файлы cookie добавляются только к текущему Домену, а также принадлежат одному домену. В этом случае ожидается ваше исключение. На боковой ноте, если я правильно ее помню, вы не можете использовать localhost для добавления файлов cookie, если вы это делаете. Изменить на IP-адрес. Кроме того, изучите файлы cookie, которые вы получаете специально для домена и информации об истечении срока действия. См., Если они возвращают null

Edit

Я сделал этот простой тест в Gmail, чтобы показать, что вы сделали неправильно. Сначала я не заметил, что вы пытаетесь захватить частичный cookie, пару и добавить это в домен. Поскольку в файле cookie нет информации о домене, пути, истечении срока действия и т.д., Она пыталась добавить файл cookie в текущий домен (127.0.0.1) и бросать какую-то вводящую в заблуждение информацию, которая не совсем понятна. Обратите внимание: для того, чтобы быть допустимым файлом cookie, он должен иметь правильную информацию о домене и истечении срока действия, которой вы отсутствовали.

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()

Выход консоли:

D:\Python34\python.exe "D:\Program Files (x86)\JetBrains\PyCharm Educational Edition 1.0.1\helpers\pycharm\utrunner.py" E:\work\selenium.python\selenium\python\FirstTest.py:: CookieManagerTest true Тестирование началось в 9:59 утра...

******* Частичная информация cookie, которую вы делаете *******

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

Полное Cookie, включая информацию о домене и истечении срока действия

{'httponly': False, 'name': '*******', 'value': 'ID = *******: FF = 0: LD = en: TM = * ******: LM = 1432393656: GM = 1: S = iNakWMI5h_2cqIYi ',' path ':'/',' expires ':' Mon, 22 мая 2017 15:07:36 GMT ',' secure ': False, 'expiry': *******, 'domain': '.google.com'}

Примечание. Я просто заменил некоторую информацию *******

Ответ 2

Я собирался просто добавить комментарий к нижней части того, что сказал @Saifur выше, но я решил, что у меня достаточно нового контента, чтобы получить полный комментарий.

Откровение для меня, с той же самой ошибкой, заключалось в том, что использование Selenium работает точно так же, как если бы вы фактически открывали свой браузер и физически щелкали и набирали вещи. Имея это в виду, если вы введете пользователя/перейдите в Selenium и нажмите click(), ваш драйвер Selenium, после успешного аутентификации, автоматически получит в нем файл cookie. Таким образом, отрицание любой необходимости разбить мой сохраненный (вероятно, скоро истечет) cookie. Я чувствовал себя немного глупо, понимая это. Сделано все намного проще.

Используя приведенный выше код @Saifur в качестве шаблона, я внес некоторые корректировки и удалил то, что, по моему мнению, немного избыточно для целого класса для выполнения в этом примере.

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()

отсюда вы можете перейти на страницу, которую хотите адресовать

driver.get(url2)

обратите внимание:, если у вас есть современный сайт, который загружается автоматически при прокрутке вниз, может быть удобно использовать это:

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

Я также хотел бы отметить, @simeg, что Selenium автоматически должен ждать, пока страница вернется, что она загружена (и да, у меня была проблема AJAX, на которую ссылаются, поэтому иногда это необходимо подождать несколько секунд - какая страница занимает больше 30 секунд, чтобы загрузить?!). То, как вы выполняете команду wait, просто ждет загрузки PhantomJS, а не самой фактической страницы, поэтому мне кажется, что мне не нужна встроенная функция:

Метод driver.get будет перемещаться по странице, заданной URL-адресом. WebDriver будет ждать, пока страница полностью загрузится (то есть событие "onload" ), прежде чем вернуть управление вашему тесту или script. Стоит отметить, что если ваша страница использует большое количество AJAX при загрузке, то WebDriver может не знать, когда она полностью загружена.

источник: http://selenium-python.readthedocs.io/getting-started.html#example-explained

Надеюсь, это поможет кому-то!

Ответ 3

Некоторые веб-страницы используют слишком много ключей в файлах cookie, не поддерживаемых webdriver, тогда вы получаете "errorMessage": "Может устанавливать только Cookies для текущего домена", даже если вы на 100% уверены, что устанавливаете файлы cookie для текущий домен. Примером такой веб-страницы является /fooobar.com/...". В этом случае вам нужно убедиться, что в файлы cookie добавлены только необходимые ключи, как указано в некоторых предыдущих сообщениях.

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

В зависимости от контекста некоторые веб-страницы используют слишком мало ключей в файлах cookie, которые требуются webdriver, после чего вы получаете "errorMessage": "Можно только установить Cookies для текущего домена", после устранения первой проблемы. Примером такой веб-страницы является https://github.com/ ". Вам нужно добавить ключ" expiry" в файлы cookie для этой веб-страницы.

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

Объединяя их вместе, полный код выглядит следующим образом:

# uncommented one of the following three URLs to test
#targetURL = "http://pythonscraping.com"
targetURL = "http://qaru.site/"
#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)