我要实现的目标
我正在尝试登录一个必须使用硒无头启用cookie的网站,我正在为驾驶员使用phantomjs。
问题
i首先使用硒IDE记录了该过程,该过程使用Firefox(不是无头)录制了它的工作正常。然后,我将代码导出到Python,现在我无法登录,因为它丢了一个错误,说"只能为当前域设置cookie"。我不知道为什么我会遇到这个问题,我不在正确的域名吗?
代码
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)
...
我尝试了
我尝试将cookie保存在一个dict中,转到另一个域,返回原始域并添加了cookie然后尝试登录,但它仍然不起作用(如该线程中所建议)
任何帮助都将不胜感激。
研究每个cookie对。我遇到了类似的问题,一些cookie属于Google。您需要确保仅将Cookie添加到当前域,并且还属于同一域。在这种情况下,您的例外是预期的。附带说明,如果我没记错的话,如果您这样做,则不能使用localhost
添加cookie。更改为IP地址。另外,调查您获得的特殊域和到期信息的cookie。看,如果他们返回null
编辑
我对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 infon")
print(s_cookie)
# driver.add_cookie(s_cookie)
def tearDown(self):
self.driver.quit()
控制台输出:
d: python34 python.exe" d: program文件(x86) jetbrains pycharm教育版1.0.1 helpers pycharm pycharm pycharm utrunner.py" firstTest.py :: cookiemanagertest true 测试从上午9:59开始...
*******您正在做的部分cookie信息*******
{'pref':'id = *******:ff = 0:ld = en:tm = *******:lm = *******:gm = 1:s = *******'}
完整的cookie,包括域和有效信息
{'httponly':false,'名称':'*******','value':'id = *******:ff = 0:ld = en:tm =********:lm = 1432393656:gm = 1:s = inakwmi5h_2cqiyi','path':'/','/',','expires':'星期一,2017年5月22日,2017年5月22日15:07:36 GMT gmt','secure','secure':false," expry':*******,'域':'.google.com'}
注意:我只是用
*******
替换了一些信息
我只会在@Saifur上面说的内容的底部添加评论,但是我认为我有足够的新内容来保证一个完整的评论。
对我来说,启示段完全相同的错误是,使用硒的工作原理与您实际上打开浏览器并进行物理单击和键入内容完全相同。考虑到这一点,如果您输入用户/传递到硒并按click()
,您的硒驱动器将在成功的正义驾驶时自动带有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,硒自动应该等到该页面返回到已加载的页面(是的,我已经提到了Ajax问题,因此有时是必要的等待几秒钟 - 哪个页面需要更多的30秒才能加载?!)。您正在运行Wait命令的方式只是在等待Phantomjs加载,而不是实际页面本身,因此考虑到内置功能,我似乎没有用:
驱动程序方法将导航到URL给出的页面。WebDriver将等到该页面已满载(即" Onload"事件已经发射),然后将控件返回您的测试或脚本。值得注意的是,如果您的页面在加载上使用了很多Ajax,那么WebDriver可能不知道它何时完全加载。
来源:http://selenium-python.readthedocs.io/getting-started.html#example-解释
希望这对某人有帮助!
某些网页在不支持WebDriver支持的cookie中使用过多的键,然后您会得到" errormessage":"即使您是100%,也只能为当前域设置cookie'确保您正在为当前域设置cookie。此类网页的一个示例是" https://stackoverflow.com/"。在这种情况下,您需要确保仅在以前的某些帖子中提到的cookie中仅添加所需的密钥。
。driver.add_cookie({k: cookie[k] for k in ('name', 'value', 'domain', 'path', 'expiry') if k in cookie})
在约束中,某些网页在cookie中使用的密钥很少,这是WebDriver所要求的,然后在解决第一个问题之后,您将获得一个" errormessage":"只能为当前域设置cookie"。此类网页的一个示例是" https://github.com/"。您需要在此网页的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 = "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)