一、解决bug:Selenium with PhantomJS,重构SeleniumeDownloader底层浏览器驱动

0、小背景:

想爬取外网steam的数据,但是steam官网在海外,加上steam处于反爬考虑,对于异步数据-json数据进行处理,导致如果直接去拿人家的ajax接口作为请求url进行爬取就爬取得到一堆乱码的没用数据。---解决:使用Selenium 模拟用户使用浏览器(通过js渲染),然后再解析处理selenium下载器下载下来的数据。

但是一开始,项目中selenium底层是使用phantomjs 作为驱动器(浏览器),出现了如下的一系列:

1、bug 截图

  • 找不到变量xxx

  • 报错信息:
[ERROR - 2023-03-07T12:00:29.232Z] Session [258893b0-bcdf-11ed-9fc2-3f99c08d4ed8] - page.onError - msg: ReferenceError: Can't find variable: InitMiniprofileHovers

  phantomjs://platform/console++.js:263 in error
[ERROR - 2023-03-07T12:00:29.233Z] Session [258893b0-bcdf-11ed-9fc2-3f99c08d4ed8] - page.onError - stack:
global code (https://store.steampowered.com/charts/topselling/SG:671) phantomjs://platform/console++.js:263 in error
[ERROR - 2023-03-07T12:00:30.743Z] Session [258893b0-bcdf-11ed-9fc2-3f99c08d4ed8] - page.onError - msg: ReferenceError: Can't find variable: WebStorage phantomjs://platform/console++.js:263 in error
[ERROR - 2023-03-07T12:00:30.744Z] Session [258893b0-bcdf-11ed-9fc2-3f99c08d4ed8] - page.onError - stack:
(anonymous function) (https://store.st.dl.eccdnx.com/public/shared/javascript/shared_responsive_adapter.js?v=TNYlyRmh1mUl&l=schinese&_cdn=china_eccdnx:43)
l (https://store.st.dl.eccdnx.com/public/shared/javascript/jquery-1.8.3.min.js?v=.TZ2NKhB-nliU&_cdn=china_eccdnx:2)
fireWith (https://store.st.dl.eccdnx.com/public/shared/javascript/jquery-1.8.3.min.js?v=.TZ2NKhB-nliU&_cdn=china_eccdnx:2)
ready (https://store.st.dl.eccdnx.com/public/shared/javascript/jquery-1.8.3.min.js?v=.TZ2NKhB-nliU&_cdn=china_eccdnx:2)
A (https://store.st.dl.eccdnx.com/public/shared/javascript/jquery-1.8.3.min.js?v=.TZ2NKhB-nliU&_cdn=china_eccdnx:2) phantomjs://platform/console++.js:263 in error
[ERROR - 2023-03-07T12:00:30.746Z] Session [258893b0-bcdf-11ed-9fc2-3f99c08d4ed8] - page.onError - msg: ReferenceError: Can't find variable: GetNavCookie

2、待爬取的页面是存在该变量的:InitMiniprofileHovers、GetNavCookie

3、调试-核心步骤

  • 断点入口
Page page = downloader.download(request, this);//爬虫任务的下载器,开始下载页面
  • SeleniumDownloader
//获取到web驱动器
webDriver = webDriverPool.get();
//驱动器下载页面
webDriver.get(request.getUrl());//这里出错

webDriver变量的情况:

  • RemoteWebDriver
 this.execute("get", ImmutableMap.of("url", url));//执行下载命令

response = this.executor.execute(command);//响应体,即执行命令后的结果
//command 只是一个封装了sessionId, driverCommand-get, 请求参数url的对象
  • PhantomJSCommandExecutor
Response var2 = super.execute(command);

...

4、分析错误原因:

报错原因:是phantomis设计的不够合理: 在页面寻找不到dom元素的时候,合理设计应该返回nul,而不应该throw异常。

网友的错误原因--加密方式,理由:PhantomJS使用的加密方式是SSLv3,有些网站用的是TLS。

解决加密问题的方法:--ignore-ssl-errors=true 和 --ssl-protocol=any

▷ 自己的项目中的 web驱动器/浏览器(排除加密方式的原因):

5、小心得:

phantomjs在对ES6的支持上天生有坑,前端使用ES6的网站都不建议用phantomis去跑。

6、解决:使用 chrome 代替 PhantomJS

7、新的问题:chrome 解析外网的时候,不稳定

  • 解决---vpn
  • 现在思路就变成了Selenium 在调用浏览器 chrome 的时候,开vpn,默认集成到 Selenium中的浏览器,都是普通纯净的浏览器。

发现微软的浏览器Edge 打开steam 官网,不开vpn,也很流畅,不过要是steam的链接带上地理位置,例如香港,又打不开了,解决:vpn

二、改写Selenium的浏览器-目的为了添加代理

1、基本思路:先理清业务的逻辑

发现,在项目调用完爬虫框架的调度器后,下载器开始发挥作用。

case CHROME:
if (isWindows) {
System.setProperty("selenuim_config", "C:\\data\\config\\config-chrome.ini");
SeleniumDownloader seleniumDownloader = new SeleniumDownloader("C:\\data\\config\\chromedriver.exe");
// 浏览器打开10s后才开始爬取数据
seleniumDownloader.setSleepTime(10 * 1000);
autoSpider.setDownloader(seleniumDownloader);
}

业务中,我们是通过了创建了SeleniumDownloader的下载器来下载页面,但是确定就是底层的浏览器是纯净普通版的浏览器。

看到业务在创建SeleniumDownloader的下载器的时候,给它注入了一个配置文件config-chrome.ini,

2、个人解决思路1:考虑把代理的options 也通过这个配置文件注入

但是发现这个配置文件是一个启动文件,里面并没options的属性可以配置。

启动文件的配置,没法实现

3、个人解决思路2:看看SeleniumDownloader的下载器底层的浏览器驱动池WebDriverPool

是否有暴露给外界什么属性可以配置options,阅读源码后,发现它只暴露一个属性就是配置启动文件config-chrome.ini。

public void configure() throws IOException {
// Read config file
sConfig = new Properties();
String configFile = DEFAULT_CONFIG_FILE;
if (System.getProperty("selenuim_config")!=null){
configFile = System.getProperty("selenuim_config");
}
sConfig.load(new FileReader(configFile)); // Prepare capabilities
sCaps = new DesiredCapabilities();
sCaps.setJavascriptEnabled(true);
sCaps.setCapability("takesScreenshot", false); String driver = sConfig.getProperty("driver", DRIVER_PHANTOMJS); // Fetch PhantomJS-specific configuration parameters
......
}

4、个人解决思路3:重写底层的浏览器驱动池WebDriverPool,然后再重写一个调用该WebDriverPool的下载器

下载器和驱动器管理池都是在官网提供的源码的基础进行修改;

SeleniumDownloader2:在SeleniumDownloader基础上新增了代理枚举属性proxyEnum,并使用了自己重写的浏览器驱动池WebDriverPool2

WebDriverPool2:改写了 WebDriverPool的构造器,以及改写了初始化 WebDriver实例的configure方法(目的,就是为了增加上像代理等的options选项)

  • 当然,还增加了一个轮询方法incrForLoop,目的就是为了获得代理列表的索引

■ WebDriverPool2:

  • 用省略号表示代理和官网的是一摸一样的!

  • 细节: ChromeOptions需要设置ssl协议(官网给出的demo没加,导致我开vpn一直没成功,又没提示.....)

    ​ 分析和解决:因为https=http+ssl/tls,我们通过浏览器访问的时候,浏览器会把所有url地址都处理成安全通信协议,所以代码中需要配置ssl协议

public class WebDriverPool2 {
......
/** 代理枚举参数 */
private final ProxyEnum proxyEnum;
/** 代理列表 */
private List<String> proxies;
/** ip代理列表的索引 */
private final AtomicInteger pointer = new AtomicInteger(-1);
...... /**
* 初始化一个 WebDriver 实例
* @throws IOException 异常
*/
public void configure() throws IOException {
......
if (isUrl(driver)) {
sCaps.setBrowserName("phantomjs");
mDriver = new RemoteWebDriver(new URL(driver), sCaps);
} else if (driver.equals(DRIVER_FIREFOX)) {
mDriver = new FirefoxDriver(sCaps);
} else if (driver.equals(DRIVER_CHROME)) {
if(proxyEnum == ProxyEnum.VPN_ENABLE || proxyEnum == ProxyEnum.PROXY_ENABLE){
//给谷歌浏览器,添加上ip代理或vpn等options
ChromeOptions options = new ChromeOptions();
//禁止加载图片
options.addArguments("blink-settings=imagesEnabled=false");
Proxy proxy = new Proxy();
String httpProxy = proxies.get(incrForLoop());
// 需要设置ssl协议
proxy.setHttpProxy(httpProxy).setSslProxy(httpProxy);
options.setCapability("proxy",proxy);
sCaps.setCapability(ChromeOptions.CAPABILITY, options);
logger.info("chrome webDriver proxy is : " + proxy);
}
mDriver = new ChromeDriver(sCaps);
} else if (driver.equals(DRIVER_PHANTOMJS)) {
mDriver = new PhantomJSDriver(sCaps);
}
} /**
* 轮询:从代理列表选出一个代理的索引
* @return 索引
*/
private int incrForLoop() {
int p = pointer.incrementAndGet();
int size = proxies.size();
if (p < size) {
return p;
}
while (!pointer.compareAndSet(p, p % size)) {
p = pointer.get();
}
return p % size;
} public WebDriverPool2(int capacity, ProxyEnum proxyEnum, MasterWebservice masterWebservice) {
this.capacity = capacity;
//设置代理的情况
this.proxyEnum = proxyEnum;
//vpn的情况
if(proxyEnum == ProxyEnum.VPN_ENABLE){
this.proxies = masterWebservice.getVpn();
//ip代理的情况
}else if(proxyEnum == ProxyEnum.PROXY_ENABLE){
//获取动态生成的ip列表,带有端口的,参数形式举例 42.177.155.5:75114
this.proxies = masterWebservice.getProxyIps();
}
} }

■ SeleniumDownloader2:

/**
* 在SeleniumDownloader基础上新增了代理枚举属性proxyEnum
* 并且要把官网SeleniumDownloader代码中使用WebDriverPool(实际是使用上咱改写的WebDriverPool2)的方法引入,还有使用到WebDriverPool的方法
* 中,需要的属性,要注意父类中被设置私有,需要重写一下(从父类copy到子类就行啦)
*/
public class SeleniumDownloader2 extends SeleniumDownloader {
private volatile WebDriverPool2 webDriverPool; /** 代理枚举参数 */
private ProxyEnum proxyEnum;
/** 通过masterWebservice获得远程的动态ip列表 */
private MasterWebservice masterWebservice; public SeleniumDownloader2(String chromeDriverPath, ProxyEnum proxyEnum, MasterWebservice masterWebservice) {
System.getProperties().setProperty("webdriver.chrome.driver",
chromeDriverPath);
this.proxyEnum = proxyEnum;
this.masterWebservice = masterWebservice;
} ......
}

■ seleniume 包下的下载器和浏览器如下:

■ 官网提供的WebDriverPool:

package us.codecraft.webmagic.downloader.selenium;

import org.apache.log4j.Logger;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriverService;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver; import java.io.FileReader;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.atomic.AtomicInteger; /**
* @author code4crafter@gmail.com <br>
* Date: 13-7-26 <br>
* Time: 下午1:41 <br>
*/
class WebDriverPool {
private Logger logger = Logger.getLogger(getClass()); private final static int DEFAULT_CAPACITY = 5; private final int capacity; private final static int STAT_RUNNING = 1; private final static int STAT_CLODED = 2; private AtomicInteger stat = new AtomicInteger(STAT_RUNNING); /*
* new fields for configuring phantomJS
*/
private WebDriver mDriver = null;
private boolean mAutoQuitDriver = true; private static final String DEFAULT_CONFIG_FILE = "/data/webmagic/webmagic-selenium/config.ini";
private static final String DRIVER_FIREFOX = "firefox";
private static final String DRIVER_CHROME = "chrome";
private static final String DRIVER_PHANTOMJS = "phantomjs"; protected static Properties sConfig;
protected static DesiredCapabilities sCaps; /**
* Configure the GhostDriver, and initialize a WebDriver instance. This part
* of code comes from GhostDriver.
* https://github.com/detro/ghostdriver/tree/master/test/java/src/test/java/ghostdriver
*
* @author bob.li.0718@gmail.com
* @throws IOException
*/
public void configure() throws IOException {
// Read config file
sConfig = new Properties();
String configFile = DEFAULT_CONFIG_FILE;
if (System.getProperty("selenuim_config")!=null){
configFile = System.getProperty("selenuim_config");
}
sConfig.load(new FileReader(configFile)); // Prepare capabilities
sCaps = new DesiredCapabilities();
sCaps.setJavascriptEnabled(true);
sCaps.setCapability("takesScreenshot", false); String driver = sConfig.getProperty("driver", DRIVER_PHANTOMJS); // Fetch PhantomJS-specific configuration parameters
if (driver.equals(DRIVER_PHANTOMJS)) {
// "phantomjs_exec_path"
if (sConfig.getProperty("phantomjs_exec_path") != null) {
sCaps.setCapability(
PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY,
sConfig.getProperty("phantomjs_exec_path"));
} else {
throw new IOException(
String.format(
"Property '%s' not set!",
PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY));
}
// "phantomjs_driver_path"
if (sConfig.getProperty("phantomjs_driver_path") != null) {
System.out.println("Test will use an external GhostDriver");
sCaps.setCapability(
PhantomJSDriverService.PHANTOMJS_GHOSTDRIVER_PATH_PROPERTY,
sConfig.getProperty("phantomjs_driver_path"));
} else {
System.out
.println("Test will use PhantomJS internal GhostDriver");
}
} // Disable "web-security", enable all possible "ssl-protocols" and
// "ignore-ssl-errors" for PhantomJSDriver
// sCaps.setCapability(PhantomJSDriverService.PHANTOMJS_CLI_ARGS, new
// String[] {
// "--web-security=false",
// "--ssl-protocol=any",
// "--ignore-ssl-errors=true"
// }); ArrayList<String> cliArgsCap = new ArrayList<String>();
cliArgsCap.add("--web-security=false");
cliArgsCap.add("--ssl-protocol=any");
cliArgsCap.add("--ignore-ssl-errors=true");
sCaps.setCapability(PhantomJSDriverService.PHANTOMJS_CLI_ARGS,
cliArgsCap); // Control LogLevel for GhostDriver, via CLI arguments
sCaps.setCapability(
PhantomJSDriverService.PHANTOMJS_GHOSTDRIVER_CLI_ARGS,
new String[] { "--logLevel="
+ (sConfig.getProperty("phantomjs_driver_loglevel") != null ? sConfig
.getProperty("phantomjs_driver_loglevel")
: "INFO") }); // String driver = sConfig.getProperty("driver", DRIVER_PHANTOMJS); // Start appropriate Driver
if (isUrl(driver)) {
sCaps.setBrowserName("phantomjs");
mDriver = new RemoteWebDriver(new URL(driver), sCaps);
} else if (driver.equals(DRIVER_FIREFOX)) {
mDriver = new FirefoxDriver(sCaps);
} else if (driver.equals(DRIVER_CHROME)) {
mDriver = new ChromeDriver(sCaps);
} else if (driver.equals(DRIVER_PHANTOMJS)) {
mDriver = new PhantomJSDriver(sCaps);
}
} /**
* check whether input is a valid URL
*
* @author bob.li.0718@gmail.com
* @param urlString urlString
* @return true means yes, otherwise no.
*/
private boolean isUrl(String urlString) {
try {
new URL(urlString);
return true;
} catch (MalformedURLException mue) {
return false;
}
} /**
* store webDrivers created
*/
private List<WebDriver> webDriverList = Collections
.synchronizedList(new ArrayList<WebDriver>()); /**
* store webDrivers available
*/
private BlockingDeque<WebDriver> innerQueue = new LinkedBlockingDeque<WebDriver>(); public WebDriverPool(int capacity) {
this.capacity = capacity;
} public WebDriverPool() {
this(DEFAULT_CAPACITY);
} /**
*
* @return
* @throws InterruptedException
*/
public WebDriver get() throws InterruptedException {
checkRunning();
WebDriver poll = innerQueue.poll();
if (poll != null) {
return poll;
}
if (webDriverList.size() < capacity) {
synchronized (webDriverList) {
if (webDriverList.size() < capacity) { // add new WebDriver instance into pool
try {
configure();
innerQueue.add(mDriver);
webDriverList.add(mDriver);
} catch (IOException e) {
e.printStackTrace();
} // ChromeDriver e = new ChromeDriver();
// WebDriver e = getWebDriver();
// innerQueue.add(e);
// webDriverList.add(e);
}
} }
return innerQueue.take();
} public void returnToPool(WebDriver webDriver) {
checkRunning();
innerQueue.add(webDriver);
} protected void checkRunning() {
if (!stat.compareAndSet(STAT_RUNNING, STAT_RUNNING)) {
throw new IllegalStateException("Already closed!");
}
} public void closeAll() {
boolean b = stat.compareAndSet(STAT_RUNNING, STAT_CLODED);
if (!b) {
throw new IllegalStateException("Already closed!");
}
for (WebDriver webDriver : webDriverList) {
logger.info("Quit webDriver" + webDriver);
webDriver.quit();
webDriver = null;
}
} }

■ 官网提供的SeleniumDownloader:

package us.codecraft.webmagic.downloader.selenium;

import org.apache.log4j.Logger;
import org.openqa.selenium.By;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Request;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Task;
import us.codecraft.webmagic.downloader.Downloader;
import us.codecraft.webmagic.selector.Html;
import us.codecraft.webmagic.selector.PlainText; import java.io.Closeable;
import java.io.IOException;
import java.util.Map; /**
* 使用Selenium调用浏览器进行渲染。目前仅支持chrome。<br>
* 需要下载Selenium driver支持。<br>
*
* @author code4crafter@gmail.com <br>
* Date: 13-7-26 <br>
* Time: 下午1:37 <br>
*/
public class SeleniumDownloader implements Downloader, Closeable { private volatile WebDriverPool webDriverPool; private Logger logger = Logger.getLogger(getClass()); private int sleepTime = 0; private int poolSize = 1; private static final String DRIVER_PHANTOMJS = "phantomjs"; /**
* 新建
*
* @param chromeDriverPath chromeDriverPath
*/
public SeleniumDownloader(String chromeDriverPath) {
System.getProperties().setProperty("webdriver.chrome.driver",
chromeDriverPath);
} /**
* Constructor without any filed. Construct PhantomJS browser
*
* @author bob.li.0718@gmail.com
*/
public SeleniumDownloader() {
// System.setProperty("phantomjs.binary.path",
// "/Users/Bingo/Downloads/phantomjs-1.9.7-macosx/bin/phantomjs");
} /**
* set sleep time to wait until load success
*
* @param sleepTime sleepTime
* @return this
*/
public SeleniumDownloader setSleepTime(int sleepTime) {
this.sleepTime = sleepTime;
return this;
} @Override
public Page download(Request request, Task task) {
checkInit();
WebDriver webDriver;
try {
webDriver = webDriverPool.get();
} catch (InterruptedException e) {
logger.warn("interrupted", e);
return null;
}
logger.info("downloading page " + request.getUrl());
webDriver.get(request.getUrl());
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
WebDriver.Options manage = webDriver.manage();
Site site = task.getSite();
if (site.getCookies() != null) {
for (Map.Entry<String, String> cookieEntry : site.getCookies()
.entrySet()) {
Cookie cookie = new Cookie(cookieEntry.getKey(),
cookieEntry.getValue());
manage.addCookie(cookie);
}
} /*
* TODO You can add mouse event or other processes
*
* @author: bob.li.0718@gmail.com
*/ WebElement webElement = webDriver.findElement(By.xpath("/html"));
String content = webElement.getAttribute("outerHTML");
Page page = new Page();
page.setRawText(content);
page.setHtml(new Html(content, request.getUrl()));
page.setUrl(new PlainText(request.getUrl()));
page.setRequest(request);
webDriverPool.returnToPool(webDriver);
return page;
} private void checkInit() {
if (webDriverPool == null) {
synchronized (this) {
webDriverPool = new WebDriverPool(poolSize);
}
}
} @Override
public void setThread(int thread) {
this.poolSize = thread;
} @Override
public void close() throws IOException {
webDriverPool.closeAll();
}
}

三、关于Selenium 的介绍

0、官网参考资料:

1、Selenium 是什么

Selenium 是Web的自动化测试工具,可以模拟用户与浏览器交互,进行访问网站。

Selenium是一个浏览器自动化的大型项目。

它提供用于模拟用户与浏览器交互的扩展、用于扩展浏览器分配的分发服务器,以及用于实现W3C WebDriver 规范的基础结构,使您可以为所有主要 Web 浏览器编写可互换的代码。Selenium 的核心是WebDriver,它是一个编写指令集的接口,可以在许多浏览器中互换运行。

2、Selenium 作用:

自动化测试:自动化测试工具,可以模拟用户与浏览器交互,进行访问网站。

爬虫:因为Selenium可以控制浏览器发送请求,并获取网页数据,因此可以应用于爬虫领域。

Selenium 可以根据我们的指令,让浏览器自动加载页面,获取需要的数据,甚至页面截屏,或者判断网站上某些动作是否发生。

3、Selenium 实际情况

Selenium是一个Web的自动化测试工具,最初是为网站自动化测试而开发的,Selenium 可以直接运行在浏览器上,它支持所有主流的浏览器。

Selenium 自己不带浏览器,不支持浏览器的功能,它需要与第三方浏览器结合在一起才能使用。

■ 主流的浏览器驱动WebDriver:PhantomJS、chromedriver

PhantomJS:

PhantomJS 是一个基于Webkit的“无界面”(headless)浏览器,它会把网站加载到内存并执行页面上的 JavaScript,因为不会展示图形界面,所以运行起来比完整的浏览器要高效。

如果我们把 Selenium 和 PhantomJS 结合在一起,就可以运行一个非常强大的网络爬虫了,这个爬虫可以处理 JavaScrip、Cookie、headers,以及任何我们真实用户需要做的事情。

chromedriver:

注意 :chromedriver的版本要与你使用的chrome版本对应!

chromedriver版本	  支持的Chrome版本
v2.46 v71-73
v2.45 v70-72
v2.44 v69-71
v2.43 v69-71
v2.42 v68-70
v2.41 v67-69
v2.40 v66-68
v2.39 v66-68
v2.38 v65-67
v2.37 v64-66
v2.36 v63-65
v2.35 v62-64
v2.34 v61-63
v2.33 v60-62
v2.32 v59-61
v2.31 v58-60
v2.30 v58-60
v2.29 v56-58
v2.28 v55-57
v2.27 v54-56
v2.26 v53-55
v2.25 v53-55
v2.24 v52-54
v2.23 v51-53
v2.22 v49-52
v2.21 v46-50
v2.20 v43-48
v2.19 v43-47
v2.18 v43-46
v2.17 v42-43
v2.13 v42-45
v2.15 v40-43
v2.14 v39-42
v2.13 v38-41
v2.12 v36-40
v2.11 v36-40
v2.10 v33-36
v2.9 v31-34
v2.8 v30-33
v2.7 v30-33
v2.6 v29-32
v2.5 v29-32
v2.4 v29-32

4、Selenium+chromedriver 的使用:

(1) 准备工作:

Selenium:导入依赖包

chromedriver:看着你电脑的谷歌浏览器版本,下载对应的chromedriver 驱动包

(2) 使用:

public class FirstScriptTest {

    @Test
public void eightComponents() {
//通过DesiredCapabilities、options 可以给driver 配置一个选项,例如代理,禁止加载图片、去掉界面模式等
//参考:ChromeDriver:https://sites.google.com/a/chromium.org/chromedriver/capabilities
String downloadsPath = "d:\\data\\downloads";
HashMap<String, Object> chromePrefs = new HashMap<String, Object>();
chromePrefs.put("download.default_directory", downloadsPath);
ChromeOptions options = new ChromeOptions();
Proxy proxy = new Proxy();
// 需要增加设置ssl协议
proxy.setHttpProxy(VpnServerUtils.getVpnServer()).setSslProxy(VpnServerUtils.getVpnServer());
// proxy.setHttpProxy(VpnServerUtils.getVpnServer());
options.setCapability("proxy",proxy);
System.out.println("~~~~~~~~~~~~~~~~~proxy: " + proxy.getHttpProxy());
options.setExperimentalOption("prefs", chromePrefs);
DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability(ChromeOptions.CAPABILITY, options); WebDriver driver = new ChromeDriver(caps);
//浏览器驱动器请求加载页面
driver.get("https://www.selenium.dev/selenium/web/web-form.html"); //查找元素
String title = driver.getTitle();
assertEquals("Web form", title); driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500)); WebElement textBox = driver.findElement(By.name("my-text"));
WebElement submitButton = driver.findElement(By.cssSelector("button")); textBox.sendKeys("Selenium");
submitButton.click();//点击事件 WebElement message = driver.findElement(By.id("message"));
String value = message.getText();
assertEquals("Received!", value);
//结束会话
driver.quit();
}
}

如果本文对你有帮助的话记得给一乐点个赞哦,感谢!

重构SeleniumeDownloader底层浏览器驱动的更多相关文章

  1. 2.5 【配置环境】多浏览器驱动 (chrome、IE、Firefox)❀

    来源:http://blog.csdn.net/huilan_same/article/details/51896672 http://www.cnblogs.com/thinkCoding/p/64 ...

  2. selenium的Python使用(一)浏览器驱动的安装及使用

    一.selenium的安装 直接使用pip进行安装 pip install selenium    #(安装最新版本) pip install selenium==3.6.0   #(安装指定版本) ...

  3. Python3+Selenium2完整的自动化测试实现之旅(二):IE和Chrome浏览器驱动配置

    上一篇写了自动化测试需要的最基础环境配置,地址:https://www.cnblogs.com/tdp0108/p/10412073.html 当前市面上很多公司开发的应用软件都是BS架构,即基于浏览 ...

  4. web自动化测试python+selenium学习总结----selenium安装、浏览器驱动下载

    一.安装selenium 命令安装selenium库 :pip  install -U selenium 查看selenium是否安装成功:pip list PS:有时会有异常,安装失败,可以尝试去s ...

  5. selenium3环境搭建以及各浏览器驱动的使用方法

    想了解更多关于seleniu请访问selenium官网 https://www.seleniumhq.org/ 以Selenium3.0.2版本为例介绍在Python中如何安装及使用,具体操作步骤如下 ...

  6. Selenium + WebDriver 各浏览器驱动下载地址

    Chrome 点击下载chrome的webdriver: http://chromedriver.storage.googleapis.com/index.html 不同的Chrome的版本对应的ch ...

  7. Robot Framework浏览器驱动下载

    运行robot framework 有时打不开浏览器,可能用到的驱动不对,以下是各浏览器驱动下载,仅供参考!~ 各浏览器下载地址: Firefox浏览器驱动:geckodriver    https: ...

  8. Selenium3 + Python3自动化测试系列一——安装Python+selenium及selenium3 浏览器驱动

    一.安装Python https://www.python.org/downloads/ 验证Python是否安装成功.打开Windows命令提示符(cmd),输入python,回车 注意:在安装的过 ...

  9. selenium3 浏览器驱动下载及验证

    下载浏览器驱动 当selenium升级到3.0之后,对不同的浏览器驱动进行了规范.如果想使用selenium驱动不同的浏览器,必须单独下载并设置不同的浏览器驱动. 各浏览器下载地址: Firefox浏 ...

  10. seleniumWebdriver浏览器驱动信息汇总

    selenium是thoughtworks公司开发的一款开源的测试工具,主要用来做web端的自动化测试. Python安装selenium,直接使用执行pip install selenium(pyt ...

随机推荐

  1. 2022-3-16内部群每日三题-清辉PMP

    1.项目经理正在为客户管理一个跨国项目,拟采用最新技术替换其电信基础设备.项目经理得知,在某些国家,必须遵循特定的环境规定来处置被替换的硬件.在制定商业论证时,未考虑到这些规定,项目经理应该怎么做? ...

  2. docker-compose之memcached

    新建docker-compose.yml,写入以下内容 memcached: image: memcached:latest ports: - 11211:11211 启动服务 docker-comp ...

  3. ubuntu64运行32位程序安装过程

    Ubuntu运行32位程序可以使用如下方法: 第一步: 确认你有一个64位架构的内核 你可以打开终端然后输入: dpkg --print-architecture 你将会看到像下面这样的内容: amd ...

  4. HCIA-ICT实战基础09-远程接入安全管理

    HCIA-ICT实战基础-远程接入安全管理 目录 AAA概述 AAA配置实现 telnet原理与配置 Stelnet(华为ssh的另一种称呼)配置 1 AAA概述 1.1 基本概念 AAA是Authe ...

  5. 基于Python的简单读卡上位机界面

    使用到的模块,pyserial  pyqt5  pymysql (我先是实现在命令行下通过串口进行对板子硬件的控制,比如Led ,beep等,在实现检测卡(是否选卡成功),连接卡(验证哪一个扇区),读 ...

  6. 如何获取传输url后面的参数

    function GetRequest(urlStr) {//两种方式,输入链接获取或当前链接获取 if (typeof urlStr == "undefined") { var ...

  7. 我的第二次JAVA作业

    1. Java包含哪两大类数据类型?其中基本类型的每种类型的取值范围和默认值分别是多少?请编程验证. Java 的两大数据类型: 基本类型 引用类 基本数据类型: 整数类型: byte: byte 数 ...

  8. HDFS 机架感知与副本放置策略

    HDFS 机架感知与副本放置策略 机架感知(RackAwareness) 通常,大型 Hadoop 集群会分布在很多机架上,在这种情况下, 希望不同节点之间的通信能够尽量发生在同一个机架之内,而不是跨 ...

  9. libevent学习之入门--[01]概述与安装

    网上关于libevent的介绍不在少数,我相信目前看到我这篇博客时已经基本了解libevent是用来做什么的,有什么功能,在此就不重复介绍了.我会按照我学习的过程来完整记录整个库的所有核心内容和具体应 ...

  10. Debug --> 攻击方式

    1.CSRF攻击概述: CSRF(Cross Site Request Forgery, 跨站域请求伪造)是一种网络的攻击方式,它在 2007 年曾被列为互联网 20 大安全隐患之一. CSRF攻击原 ...