python selenium webdriver:使用authenticate方法

我使用
python selenium webdriver来自动化检查.

我被困在通过弹出窗口请求http身份验证的网站上.

我试图通过以下代码使用“authenticate”方法:

#init.
driver = webdriver.Firefox()
driver.get(url)
#get to the auth popup window by clicking relevant link
elem = driver.find_element_by_id("login_link")
elem.click()
#use authenticate alert method
driver._switch_to.alert.authenticate("login", "password")

与此方法相关的(稀缺)信息/文档表明它应提交所提供的凭证和&验证http auth.它没有,我收到以下错误:

File
“/usr/local/lib/python2.7/dist-packages/selenium/webdriver/common/alert.py”,
line 105, in authenticate
self.driver.execute(Command.SET_ALERT_CREDENTIALS, {‘username’:username, ‘password’:password}) File
“/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py”,
line 201, in execute
self.error_handler.check_response(response) File “/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/errorhandler.py”,
line 159, in check_response
raise exception_class(value) selenium.common.exceptions.WebDriverException: Message: Unrecognized
command: POST
/session/c30d03e1-3835-42f5-ace0-968aef486b36/alert/credentials

有什么我在这里失踪/有任何人来到同一个问题并解决它?

PS:在我的测试条件下,http://username:password@url技巧对我不起作用.

最佳答案
Basic authentication非常容易解决自动化测试,无需处理本机警报/对话框或其他浏览器差异.

我在Java世界中非常成功地使用的方法是在代码中设置一个Browsermob代理服务器并注册一个RequestInterceptor来拦截所有传入的请求(与所讨论的主机/ URL模式匹配).当你有一个需要Basic auth的请求时,add an授权HTTP头带有所需的凭据(‘Basic’是Base64编码的’user:pass’字符串.所以对于’foo:bar’你要设置值Basic Zm9vOmJhcg ==)

启动服务器,将其设置为Web代理for Selenium traffic,当发出需要身份验证的请求时,代理将添加标头,浏览器将看到它,验证凭据,而不需要弹出对话框.

尽管该技术看似费力,但通过为每个请求自动设置标头,您不必显式地将user:pass @添加到可能需要它的任何URL,其中有多种方式进入auth-ed区域.此外,与用户:pass @ users不同,您不必担心浏览器缓存(或在一定时间后停止缓存)标头或跨越HTTP / HTTPS.

该技术非常有效,但如何在Python中实现这一点?

您可以使用此Python wrapper for Browsermob,它在Python中公开其REST API.这是您需要的REST调用:

POST /proxy/[port]/headers – Set and override HTTP Request headers.
For example setting a custom User-Agent. Payload data should be json
encoded set of headers (not url-encoded)

所以,从前面的例子(伪代码):

POST localhost:8787/proxy/<proxy_port>/headers '{"Authorization": "Basic Zm9vOmJhcg=="}'

或者,对于使用Twisted的自定义Python代理服务器,您可以使用see this answer.

点赞