如何使用 Selenium 处理证书?

我正在使用 启动一个浏览器。如何处理会要求浏览器接受证书的网页(URL) ?

在 Firefox 中,我可能有一个这样的网站要求我接受它的证书,如下所示:

Firefox

在 Internet Explorer 浏览器上,我可能会看到这样的内容:

Enter image description here

在谷歌浏览器上:

Google Chrome

我重复我的问题: 当我使用 Selenium (Internet Explorer)启动浏览器(火狐浏览器和谷歌浏览器)时,如何自动接受网站的证书(Python)

171347 次浏览

It looks like it still doesn't have a standard decision of this problem. In other words - you still can't say "Okay, do a certification, whatever if you are Internet Explorer, Mozilla or Google Chrome". But I found one post that shows how to work around the problem in Mozilla Firefox. If you are interested in it, you can check it here.

For Firefox:

ProfilesIni profile = new ProfilesIni();
FirefoxProfile myprofile = profile.getProfile("default");
myprofile.setAcceptUntrustedCertificates(true);
myprofile.setAssumeUntrustedCertificateIssuer(true);
WebDriver driver = new FirefoxDriver(myprofile);

For Chrome we can use:

DesiredCapabilities capabilities = DesiredCapabilities.chrome();
capabilities.setCapability("chrome.switches", Arrays.asList("--ignore-certificate-errors"));
driver = new ChromeDriver(capabilities);

For Internet Explorer we can use:

DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true);
Webdriver driver = new InternetExplorerDriver(capabilities);

Creating a profile and then a driver helps us get around the certificate issue in Firefox:

var profile = new FirefoxProfile();
profile.SetPreference("network.automatic-ntlm-auth.trusted-uris","DESIREDURL");
driver = new FirefoxDriver(profile);

For the Firefox, you need to set accept_untrusted_certs FirefoxProfile() option to True:

from selenium import webdriver


profile = webdriver.FirefoxProfile()
profile.accept_untrusted_certs = True


driver = webdriver.Firefox(firefox_profile=profile)
driver.get('https://cacert.org/')


driver.close()

For Chrome, you need to add --ignore-certificate-errors ChromeOptions() argument:

from selenium import webdriver


options = webdriver.ChromeOptions()
options.add_argument('ignore-certificate-errors')


driver = webdriver.Chrome(chrome_options=options)
driver.get('https://cacert.org/')


driver.close()

For the Internet Explorer, you need to set acceptSslCerts desired capability:

from selenium import webdriver


capabilities = webdriver.DesiredCapabilities().INTERNETEXPLORER
capabilities['acceptSslCerts'] = True


driver = webdriver.Ie(capabilities=capabilities)
driver.get('https://cacert.org/')


driver.close()

Actually, according to the Desired Capabilities documentation, setting acceptSslCerts capability to True should work for all browsers since it is a generic read/write capability:

acceptSslCerts

boolean

Whether the session should accept all SSL certs by default.


Working demo for Firefox:

>>> from selenium import webdriver

Setting acceptSslCerts to False:

>>> capabilities = webdriver.DesiredCapabilities().FIREFOX
>>> capabilities['acceptSslCerts'] = False
>>> driver = webdriver.Firefox(capabilities=capabilities)
>>> driver.get('https://cacert.org/')
>>> print(driver.title)
Untrusted Connection
>>> driver.close()

Setting acceptSslCerts to True:

>>> capabilities = webdriver.DesiredCapabilities().FIREFOX
>>> capabilities['acceptSslCerts'] = True
>>> driver = webdriver.Firefox(capabilities=capabilities)
>>> driver.get('https://cacert.org/')
>>> print(driver.title)
Welcome to CAcert.org
>>> driver.close()

Delete all but the necessary certificate from your browser's certificate store and then configure the browser to automatically select the certificate when only one certificate is present.

Javascript:

const capabilities = webdriver.Capabilities.phantomjs();
capabilities.set(webdriver.Capability.ACCEPT_SSL_CERTS, true);
capabilities.set(webdriver.Capability.SECURE_SSL, false);
capabilities.set('phantomjs.cli.args', ['--web-security=no', '--ssl-protocol=any', '--ignore-ssl-errors=yes']);
const driver = new webdriver.Builder().withCapabilities(webdriver.Capabilities.chrome(), capabilities).build();

For Firefox Python:

The Firefox Self-signed certificate bug has now been fixed: accept ssl cert with marionette firefox webdrive python splinter

"acceptSslCerts" should be replaced by "acceptInsecureCerts"

from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.firefox.firefox_binary import FirefoxBinary


caps = DesiredCapabilities.FIREFOX.copy()
caps['acceptInsecureCerts'] = True
ff_binary = FirefoxBinary("path to the Nightly binary")


driver = webdriver.Firefox(firefox_binary=ff_binary, capabilities=caps)
driver.get("https://expired.badssl.com")

For people coming to this question related to headless chrome via python selenium, you may find https://bugs.chromium.org/p/chromium/issues/detail?id=721739#c102 to be useful.

It looks like you can either do

chrome_options = Options()
chrome_options.add_argument('--allow-insecure-localhost')

or something along the lines of the following (may need to adapt for python):

ChromeOptions options = new ChromeOptions()
DesiredCapabilities caps = DesiredCapabilities.chrome()
caps.setCapability(ChromeOptions.CAPABILITY, options)
caps.setCapability("acceptInsecureCerts", true)
WebDriver driver = new ChromeDriver(caps)

Just an update regarding this issue.

Require Drivers:

Linux: Centos 7 64bit, Window 7 64bit

Firefox: 52.0.3

Selenium Webdriver: 3.4.0 (Windows), 3.8.1 (Linux Centos)

GeckoDriver: v0.16.0 (Windows), v0.17.0 (Linux Centos)

Code

System.setProperty("webdriver.gecko.driver", "/home/seleniumproject/geckodrivers/linux/v0.17/geckodriver");


ProfilesIni ini = new ProfilesIni();




// Change the profile name to your own. The profile name can
// be found under .mozilla folder ~/.mozilla/firefox/profile.
// See you profile.ini for the default profile name


FirefoxProfile profile = ini.getProfile("default");


DesiredCapabilities cap = new DesiredCapabilities();
cap.setAcceptInsecureCerts(true);


FirefoxBinary firefoxBinary = new FirefoxBinary();


GeckoDriverService service =new GeckoDriverService.Builder(firefoxBinary)
.usingDriverExecutable(new
File("/home/seleniumproject/geckodrivers/linux/v0.17/geckodriver"))
.usingAnyFreePort()
.usingAnyFreePort()
.build();
try {
service.start();
} catch (IOException e) {
e.printStackTrace();
}


FirefoxOptions options = new FirefoxOptions().setBinary(firefoxBinary).setProfile(profile).addCapabilities(cap);


driver = new FirefoxDriver(options);
driver.get("https://www.google.com");


System.out.println("Life Title -> " + driver.getTitle());
driver.close();

In selenium python, you need to set desired_capabilities as:

desired_capabilities = {
"acceptInsecureCerts": True
}

I was able to do this on .net c# with PhantomJSDriver with selenium web driver 3.1

 [TestMethod]
public void headless()
{




var driverService = PhantomJSDriverService.CreateDefaultService(@"C:\Driver\phantomjs\");
driverService.SuppressInitialDiagnosticInformation = true;
driverService.AddArgument("--web-security=no");
driverService.AddArgument("--ignore-ssl-errors=yes");
driver = new PhantomJSDriver(driverService);


driver.Navigate().GoToUrl("XXXXXX.aspx");


Thread.Sleep(6000);
}

For those who come to this issue using Firefox and the above solutions don't work, you may try the code below (my original answer is here).

from selenium import webdriver


profile = webdriver.FirefoxProfile()
profile.DEFAULT_PREFERENCES['frozen']['marionette.contentListener'] = True
profile.DEFAULT_PREFERENCES['frozen']['network.stricttransportsecurity.preloadlist'] = False
profile.DEFAULT_PREFERENCES['frozen']['security.cert_pinning.enforcement_level'] = 0
profile.set_preference('webdriver_assume_untrusted_issuer', False)
profile.set_preference("browser.download.folderList", 2)
profile.set_preference("browser.download.manager.showWhenStarting", False)
profile.set_preference("browser.download.dir", temp_folder)
profile.set_preference("browser.helperApps.neverAsk.saveToDisk",
"text/plain, image/png")
driver = webdriver.Firefox(firefox_profile=profile)

And in C# (.net core) using Selenium.Webdriver and Selenium.Chrome.Webdriver like this:

ChromeOptions options = new ChromeOptions();
options.AddArgument("--ignore-certificate-errors");
using (var driver = new ChromeDriver(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),options))
{
...
}

Whenever I run into this issue with newer browsers, I just use AppRobotic Personal edition to click specific screen coordinates, or tab through the buttons and click.

Basically it's just using its macro functionality, but won't work on headless setups though.

I ran into the same issue with Selenium and Behat. If you want to pass the parameters via behat.yml, here is what it needs to look like:

default:
extensions:
Behat\MinkExtension:
base_url: https://my-app.com
default_session: selenium2
selenium2:
browser: firefox
capabilities:
extra_capabilities:
acceptInsecureCerts: true

I had the exact same issue. However when I tried opening the website manually in the browser the certificate was correct, but in the details the name was "DONOTTRUST".

The difference of certificate was caused by Fiddler that was running in background and decrypting all HTTPS content before reencrypting it.

To fix my problem, just close Fiddler on machine. If you need to keep Fiddler opened, then you can uncheck Decrypt SSL in Fiddler Settings.

WebDriverManager.chromedriver().setup();
ChromeOptions options = new ChromeOptions();
options.addArguments("--ignore-certificate-errors");
driver = new ChromeDriver(options);

I have used it for Java with Chrome browser it is working nice

    ChromeOptions options = new ChromeOptions().addArguments("--proxy-server=http://" + proxy);
options.setAcceptInsecureCerts(true);

For .NET, what worked for me was the following...

var chromeOptions = new ChromeOptions { AcceptInsecureCertificates = true };

Pretty much, it tells the ChromeDriver options not to halt browser execution when an insecure certificate is detected, and to proceed as normal.