配置要点:
1.webdriver要和浏览器版本对应,chrome使用chromedriver和chrome浏览器,firefox使用geckodrive和firefox浏览器
2.支持headless:本地开发使用mac环境,默认支持;linux需要安装xvf8(虚拟GUI)
3.maven项目构建,使用selenium-3.9.1或者最新版本
4.linux配置参考:chrome: blog.csdn.net/qq_39802740… ; firefox: blog.csdn.net/u014283248/… www.xnathan.com/2017/12/04/…
chrome启动参数参考: peter.sh/experiments…
1.系统环境变量配置:webdriver.chrome.driver=DRIVER_PATH
2.常用options配置:
—headless | 无浏览器模式 |
---|---|
--no-sandbox | 非沙盒模式,linux部署必填 |
--disable-gpu | 禁用gpu,liinux部署需填,防止未知bug |
blink-settings=imagesEnabled=false | 不加载图片 |
--user-agent=ua值 | 设置ua |
3.webdriver实例化:
//设置系统环境变量 System.setProperty("webdriver.chrome.driver", env.getProperty("path.chrome.driver")); WebDriver webDriver = null; try{ ChromeOptions options = new ChromeOptions(); options.addArguments("--headless"); //无浏览器模式 options.addExtensions(new File(env.getProperty("path.chrome.proxy")));//增加代理扩展 webDriver = new ChromeDriver(options);//实例化 }catch(Exception e){ e.printStackTrace(); }finally{ //使用完毕,关闭webDriver if(webDriver != null){ webDriver.quit(); } } 复制代码
1.系统环境变量配置:webdriver.gecko.driver=DRIVER_PATH
2.常用options配置:
—headless | 无浏览器模式 |
---|---|
--no-sandbox | 非沙盒模式,linux部署必填 |
--disable-gpu | 禁用gpu,liinux部署需填,防止未知bug |
--user-agent=ua值 | 设置ua |
preference配置:
permissions.default.image | 2 | 不加载图片 |
---|---|---|
3.webdriver实例化:
//设置系统环境变量 System.setProperty("webdriver.gecko.driver", env.getProperty("path.gecko.driver")); WebDriver webDriver = null; try{ FirefoxOptions options = new FirefoxOptions(); options.addArguments("--headless"); //无浏览器模式 FirefoxProfile profile = new FirefoxProfile(); profile.addExtensions(new File(env.getProperty("path.chrome.proxy")));//增加代理扩展 profile.setPreference("permissions.default.image", 2);//不显示图片 options.setProfile(profile); //实例化 webDriver = new FirefoxDriver(options); }catch(Exception e){ e.printStackTrace(); }finally{ //使用完毕,关闭webDriver if(webDriver != null){ webDriver.quit(); } } 复制代码
4.注意:默认加载会屏蔽部分请求(js请求等)
参考: www.cnblogs.com/linxinmeng/…
1.获取页面:driver.get(url);
2.关闭页面:driver.close(); 关闭进程:driver.quit();
1.线程强制休眠等待,Thread.sleep(3000);
2.隐式等待(全局等待),对所有操作都设置的等待时间,超时会抛异常,driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
3.显式等待(可控等待, 推荐使用 ),可以对单一操作设置等待触发事件及等待时间,可自定义事件,超时会抛异常
WebDriverWait wait = new WebDriverWait(webDriver, 60);//初始化等待60s wait.until(ExpectedConditions.presenceOfElementLocated(By.id("xx")));//等待xx元素出现 //自定义等待事件 WebElement frame = wait.until((ExpectedCondition<WebElement>) driver -> { WebElement element = driver.findElement(By.id("iframepage")); return element; }); 复制代码
String page = driver.getPageSource();//获取网页全部信息 String url = driver.getCurrentUrl();//获取当前页url WebElement element = driver.findElement(By.id("xx"));//获取元素 element.sendKeys("test");//设置元素值 element.click();//点击元素 element.sendKeys(Keys.BACK_SPACE);//空格键盘事件模拟 复制代码
1.窗口操作
String handle = driver.getWindowHandle();//获取当前窗口句柄 Set<String> handles = driver.getWindowHandles();//获取全部窗口句柄 //切换到另一窗口 for(String h : handles){ if(!h.equals(handle)){ driver.switchTo().window(h);//切换窗口 }else{ driver.close(); } } 复制代码
2.表单操作,frame切换需要从外向内一层一层获取,可根据pageSource处理
driver.switchTo().frame("top");//切换到top Frame driver.switchTo().frame("inner");//切换到inner Frame 复制代码
3.弹窗操作
Alert alert = webDriver.switchTo().alert();//获取弹窗 if(alert != null){ alert.sendKeys("123");//设置输入框文本,只能设置一个输入框文本 alert.getText();//获取弹窗信息 alert.accept();//点击确认 alert.dismiss();//点击取消 } 复制代码
String js = "window.open('http://www.baicu.com')";//js脚本,打开一个新页面 ((JavascriptExecutor)driver).executeScript("");//执行js脚本 复制代码
介绍:整合封装简化WebDriver业务操作流程,采用工厂模式配合FindBy等注解使用
PageGenerator page = new PageGenerator(driver);//抽象page对象 //实例化LoginPage对象,并调用click方法 page.GetInstance(LoginPage.class).click("admin","123456"); 复制代码
LoginPage.java
public class LoginPage extends BasePage{ private final static String URL = "https://www.testlogin.com"; @FindBy(id = "login") private WebElement login; public LoginPage(WebDriver driver) { super(driver); } public Boolean clickLogin(String name, String pwd){ get(URL); click(login); return wait(ExpectedConditions.urlContains("main.html")); } } 复制代码
BasePage.java
public class BasePage extends PageGenerator { private Long timeOut = 60L;//默认超时时间60s public BasePage(WebDriver driver) { super(driver); } public <T> void get(String url) { driver.get(url); } public <T> T wait(ExpectedCondition<T> c){ return wait(c, timeOut); } public <T> T wait(ExpectedCondition<T> c, Long t){ WebDriverWait webDriverWait = new WebDriverWait(this.driver, t==null?timeOut:t); try{ return webDriverWait.until(c); }catch (Exception e){ return null; } } public <T> void click (T elementAttr) { if(elementAttr.getClass().getName().contains("By")) { driver.findElement((By) elementAttr).click(); } else { ((WebElement) elementAttr).click(); } } } 复制代码
PageGenerator.java
public class PageGenerator { public WebDriver driver; public PageGenerator(WebDriver driver){ this.driver = driver; } public <T extends BasePage> T GetInstance (Class<T> pageClass) { try { return PageFactory.initElements(driver, pageClass); } catch (Exception e) { e.printStackTrace(); throw e; } } } 复制代码
github.com/lightbody/b…
String proxyServer = "1.2.3.4:666"; Proxy proxy = new Proxy().setHttpProxy(proxyServer).setSslProxy(proxyServer); options.setProxy(proxy); 复制代码
使用browsermobproxy做代理(或其他代理)
//创建一个本地代理 BrowserMobProxyServer bmpServer = new BrowserMobProxyServer(); bmpServer.setChainedProxy(new InetSocketAddress("proxy.com",222));//代理地址端口 bmpServer.chainedProxyAuthorization("user","pwd",AuthType.BASIC);//代理用户名密码 bmpServer.setTrustAllServers(true);//信任所有服务 bmpServer.start(11112);//启动一个本地代理服务,并设置端口为11112,访问地址:localhost:11112 //使用本地代理 String proxyServer = "localhost:11112"; Proxy proxy = new Proxy().setHttpProxy(proxyServer).setSslProxy(proxyServer); options.setProxy(proxy); 复制代码
本地代理可单独做分布式部署,多节点,使用zk管理
1.chrome扩展:无法在headless模式下使用加载扩展,尚未解决
chromeOptions.addExtensions(new File(env.getProperty("path.chrome.proxy")));//代理扩展 需要在background.js配置代理账号密码后再打包 复制代码
参考:
2.firefox扩展:无法使用,新版本firefox由于认证问题无法加载,尚未解决
3.firefox使用close-proxy-authentication插件,需要旧版才能使用: www.site-digger.com/html/articl… addons.thunderbird.net/zh-tw/thund…
selenium新的api不再支持phantom.js,可以使用旧版api
1.设置黑名单
2.设置header
3.其他
chromium虽然是多进程执行,但是js引擎是单线程,同时打开多个窗口,只会加载一个页面,直到加载结束或打开下一个窗口才会去加载下一个页面,参考( blog.csdn.net/ouyanggengc…
firefox可以同时加载多个窗口的页面,同时会默认屏蔽一些请求
1.通过代理设置,browsermobserver
BrowserMobProxy server = new BrowserMobProxyServer(); server.blacklistRequests("http://.*//.blacklist.com/.*", 200);//方式1,设置单个黑名单 server.setBlacklist();//方式2,设置黑名单列表 复制代码
2.通过拓展设置,暂时没整透
1.采用正确连接方式
//错误 Proxy proxy = ClientUtil.createSeleniumProxy(server);//无法获取到代理的host //正确 String proxyServer = "localhost:11112"; Proxy proxy = new Proxy().setHttpProxy(proxyServer).setSslProxy(proxyServer); 复制代码
2.使用最新的maven包
developer.mozilla.org/zh-CN/docs/…
1.options禁止弹窗
2.获取alert,关闭弹窗
1.使用grid启动:chromedriver的权限要和grid的权限一致
2.启动grid节点: -Dwebdriver.chrome.driver参数放在-jar后面 java -jar -Dwebdriver.chrome.driver=/Users/apple/Downloads/chromedriver selenium-server-standalone-3.141.5.jar -role node -hub http://localhost:4444/grid/register -browser browserName=chrome