精华内容
下载资源
问答
  • mysql常见异常mysql常见异常mysql常见异常mysql常见异常mysql常见异常mysql常见异常mysql常见异常mysql常见异常mysql常见异常mysql常见异常mysql常见异常mysql常见异常mysql常见异常mysql常见异常mysql常见异常mysql...
  • jsp常见异常

    2013-07-17 22:46:30
    jsp常见异常
  • java常见异常总结

    2018-11-29 09:13:30
    java常见异常,总结java常见异常解释,很全面,解释也很周到
  • Hive常见异常处理.docx

    2020-04-21 16:18:22
    Hive常见异常处理,长期累积的经验 Hive常见异常处理
  • Java常见异常.pdf

    2021-09-30 17:31:46
    Java常见异常.pdf
  • 一些工作中用到的常见方法和异常记录

    基础配置

    说一下chrome和firefox的基础配置,首先

    chromedriver和chrome的版本对应关系看 :https://www.cnblogs.com/reform999/p/10685946.html

    firefox和geckodriver的对应关系: https://firefox-source-docs.mozilla.org/testing/geckodriver/Support.html

    chromedriver的下载地址在: http://npm.taobao.org/mirrors/chromedriver/

    geckodriver的下载地址是: https://github.com/mozilla/geckodriver/releases

    chrome和火狐的下载地址就不说了,百度一下,官网那个就是。

    下载对应版本的驱动和浏览器后:

    java:

    maven仓库 里找对应版本的依赖,记住千万别忘了 guava 这个依赖。不然你可能会经历 找不到方法,找不到类,等等一系列各种各样奇怪的问题。

    配置好selenium的依赖和驱动以及浏览器(浏览器的安装地址建议不要变动,让它自己安装就行了)后,设置系统变量,也就是把程序要的东西(驱动的地址),放到系统变量里,它会从系统变量里取。

    //chrome:
    System.setProperty("webdriver.chrome.driver", "chromedriver.exe的路径");
    //firefox:
    System.setProperty("webdriver.gecko.driver", "geckodriver.exe的路径");
    //如果浏览器安装地址变了
    //chrome:
    System.setProperty("webdriver.chrome.bin","chrome安装地址,精确到chrome.exe");
    //firefox:
    System.setProperty("webdriver.firefox.bin","firefox安装地址,精确到firefox.exe")
    

    这段代码在new WebDriver之前执行,现在可以试试:

    public static void main(String[] args) {
            System.setProperty("webdriver.chrome.driver", "chromedriver.exe的路径");
            ChromeDriver driver = null;
            try{
                driver = new ChromeDriver();
                driver.get("http://www.baidu.com");
                ((JavascriptExecutor) driver).executeScript("document.body.style.fontSize = '30px';document.body.innerHTML='<p1>hello world~<br/><span id=\"close\">5</span>秒后页面关闭</p1>';setInterval(()=>{let time=document.getElementById('close');time.innerText=(time.innerText-1)},1000);");
                Thread.sleep(5000L);
            }catch(Exception e){
                e.printStackTrace();
            }finally{
                //养成良好的习惯,用完后quit掉。
                if(null!=driver){
                    driver.quit();
                }
            }
        }
    

    python:

    pip install selenium
    然后就能用了(驱动和浏览器还是要下载的)。。

    if __name__ == '__main__':
        driver = None
        try:
            driver = webdriver.Chrome(executable_path='chromedriver.exe的路径')
            driver.get("http://www.baidu.com")
            driver.execute_script("document.body.style.fontSize = '30px';document.body.innerHTML='<p1>hello world~<br/><span id=\"close\">5</span>秒后页面关闭</p1>';setInterval(()=>{let time=document.getElementById('close');time.innerText=(time.innerText-1)},1000);")
            time.sleep(5)
        except Exception as e:
            print(e)
        finally:
            # 养成好习惯,用完后quit掉
            driver.quit()
    
    

    2020.03.31

    开发者模式

    该模式在chrome老版本可用,79+版本navigator.webdriver仍为true。(新版本消除navigator.webdriver方法参考目录上的2020.07.23(79+版本消除webdriver特征)

    ChromeOptions options = new ChromeOptions();
    options.setExperimentalOption("excludeSwitches", Collections.singletonList("enable-automation"));
    WebDriver driver = new ChromeDriver(options);
    

    设置有认证的http代理

    目的是让chrome打开时加载浏览器插件,所以要先生成浏览器插件。(Proxy是封装的一个类,只需要有ip,端口,用户名和密码就行了)
    由于没有sock5代理,sock5的认证代理没法测试,这里用的是http代理,公司亲测此种方法可行,用了2年多,平时也在用。

    private static ChromeOptions setProxyChrome(Proxy proxy) throws Exception{
            ChromeOptions options = new ChromeOptions();
            if(null==proxy||StringUtils.isEmpty(proxy.getIp())){
                return options;
            }
            FileWriter fileWriter1 = null;
            FileWriter fileWriter2 = null;
            String driverPath = getDriverPath();
            String jsonFilePath = driverPath + "manifest.json";
            String jsFilePath = driverPath + "background.js";
            String zipFilePath = driverPath + "proxy.zip";
            File jsonFile = new File(jsonFilePath);
            File zipFile = new File(zipFilePath);
            File jsFile = new File(jsFilePath);
            try {
                String js = "var config={mode:\"fixed_servers\",rules:{singleProxy:{scheme:\"http\",host:\"" + proxy.getIp() + "\",port:" + proxy.getPort() + "},bypassList:[\"\"]}};chrome.proxy.settings.set({value:config,scope:\"regular\"},function(){});function callbackFn(details){return{authCredentials:{username:\"" + proxy.getProxyUser() + "\",password:\"" + proxy.getProxyPass() + "\"}};}chrome.webRequest.onAuthRequired.addListener(callbackFn,{urls:[\"<all_urls>\"]},['blocking']);";
                String json = "{\"version\":\"1.0.0\",\"manifest_version\":2,\"name\":\"Chrome Proxy\",\"permissions\":[\"proxy\",\"tabs\",\"unlimitedStorage\",\"storage\",\"<all_urls>\",\"webRequest\",\"webRequestBlocking\"],\"background\":{\"scripts\":[\"background.js\"]},\"minimum_chrome_version\":\"22.0.0\"}";
                if(!jsFile.exists()){
                    jsFile.createNewFile();
                }
                if(!jsonFile.exists()){
                    jsonFile.createNewFile();
                }
                fileWriter1 = new FileWriter(jsFilePath);
                fileWriter2 = new FileWriter(jsonFilePath);
                fileWriter1.write(js);
                fileWriter2.write(json);
    
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                try{
                    if(null!=fileWriter1){
                        fileWriter1.flush();
                        fileWriter1.close();
                    }
                    if(null!=fileWriter2){
                        fileWriter2.flush();
                        fileWriter2.close();
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
            try {
                File[] files = new File[]{jsFile, jsonFile};
                zipFile(files, zipFile);
                options.addExtensions(zipFile);
            }catch (Exception e){
                e.printStackTrace();
            }
            return options;
        }
    
    	private static void zipFile(File[] srcFiles, File zipFile){
            if (!zipFile.exists()) {
                try {
                    zipFile.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            FileOutputStream fileOutputStream = null;
            ZipOutputStream zipOutputStream = null;
            FileInputStream fileInputStream = null;
    
            try {
                fileOutputStream = new FileOutputStream(zipFile);
                zipOutputStream = new ZipOutputStream(fileOutputStream);
                ZipEntry zipEntry = null;
                for (int i = 0; i < srcFiles.length; i++) {
                    fileInputStream = new FileInputStream(srcFiles[i]);
                    zipEntry = new ZipEntry(srcFiles[i].getName());
                    zipOutputStream.putNextEntry(zipEntry);
                    int len;
                    byte[] buffer = new byte[1024];
                    while ((len = fileInputStream.read(buffer)) > 0) {
                        zipOutputStream.write(buffer, 0, len);
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                try{
                    if(null!=zipOutputStream){
                        zipOutputStream.close();
                    }
                    if(null!=fileOutputStream){
                        fileOutputStream.close();
                    }
                    if(null!=fileInputStream){
                        fileInputStream.close();
                    }
    
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    

    让selenium接管人为打开的chrome

    接管selenium打开的浏览器看这里

    这里参考了python控制已经打开chrome的做法,具体做法参考:
    https://www.cnblogs.com/lovealways/p/9813059.html
    java代码:

         ChromeOptions options = new ChromeOptions();
         options.setExperimentalOption("debuggerAddress","127.0.0.1:9222");
         ChromeDriver driver = new ChromeDriver(options);
    

    2020.07.23(79+版本消除webdriver特征)

    更新,开发者模式在79版本以前能用,详情点击这里,参考这个问答,79版本以后消除navigator.webdriver使用

    ChromeOptions options = new ChromeOptions();
    options.addArguments("--disable-blink-features=AutomationControlled");
    WebDriver driver = new ChromeDriver(options);
    

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    2020.08.12(增加chromeDriver参数,解决大部分特征识别,看代码里的注释。。)

    这里再增加几个常用的参数
    关于个人用户文件夹地址:
    chrome:地址栏输入 chrome://version/ 个人资料路径 最后一个文件夹之前的就是。
    firefox:地址栏输入 about:profiles 正在使用的那个就是 一般默认default-release

    java:

    //下载配置
    HashMap<String, Object> chromePrefs = new HashMap<>();
    chromePrefs.put("download.default_directory", "文件下载路径");
    chromePrefs.put("profile.default_content_settings.popups", 0);//下载不弹框
    chromePrefs.put("profile.default_content_setting_values.images", 2);//禁止显示图片
    chromePrefs.put("browser.download.useDownloadDir", true);//使用用户下载文件夹
    chromePrefs.put("profile.default_content_setting_values.automatic_downloads",1);//多文件下载总是允许
    chromePrefs.put("profile.default_content_setting_values.media_stream_mic",1);//允许麦克风
    chromePrefs.put("profile.default_content_setting_values.media_stream_camera",1);//允许摄像头
    //消除特征配置
    ChromeOptions options = new ChromeOptions();
    options.addArguments("--disable-blink-features=AutomationControlled");
    //使用平时打开的用户数据文件夹打开chrome(这样有些网站不用登录,有些网站会记录密码,而且配合消除特性的参数,大概率不会触发滑块)
    options.addArguments("--user-data-dir=C:\\Users\\Administrator\\AppData\\Local\\Google\\Chrome\\User Data");
    options.setExperimentalOption("prefs", chromePrefs);
    

    python:

    options = webdriver.ChromeOptions()
    # 下载配置
    prefs = {
    	"download.default_directory": "文件下载路径",
    	"profile.default_content_settings.popups": 0,
    	"profile.default_content_setting_values.images": 2,
    	"browser.download.useDownloadDir": true,
    	"profile.default_content_setting_values.automatic_downloads": 1,
    	"profile.default_content_setting_values.media_stream_mic": 1,
    	"profile.default_content_setting_values.media_stream_camera": 1
    }
    options.add_experimental_option("prefs", prefs)
    # 设置用户数据文件夹 chrome打开时加载的文件夹
    options.add_argument("--user-data-dir=C:\\Users\\Administrator\\AppData\\Local\\Google\\Chrome\\User Data")
    # 消除特征 
    options.add_argument("--disable-blink-features=AutomationControlled")
    driver = webdriver.Chrome(chrome_options = options)
    

    2020.08.13(火狐参数)

    增加几个火狐的参数(我已经弃用火狐,限制太多了):

    final FirefoxOptions fopts = new FirefoxOptions();
    ProfilesIni allProfiles = new ProfilesIni();
    /**
    * 获取默认文件夹的方法:
    * 打开常用的火狐,地址栏输入about:profiles ,回车 ,找到正在使用的配置文件 后面的default,default-release就是用户配置文件夹
    */
    FirefoxProfile firefoxProfile = allProfiles.getProfile("用户文件夹");//默认default
    firefoxProfile.setPreference("dom.webdriver.enabled", false);//消除navigator.webdriver
    firefoxProfile.setPreference("browser.download.folderList", 2);//下载到用户配置文件夹
    firefoxProfile.setPreference("browser.download.manager.showWhenStarting",false);//下载是否弹框
    firefoxProfile.setPreference("browser.download.dir", "下载文件夹路径");
    firefoxProfile.setPreference("permissions.default.image", 2);//禁用图片
    fopts.setProfile(firefoxProfile);
    WebDriver driver = new FirefoxDriver(fopts);
    

    以下内容来自 https://blog.csdn.net/qq_37931379/article/details/104595450 (仅供参考)

    	FirefoxOptions options = new FirefoxOptions();
    	//声明一个profile对象
    	FirefoxProfile profile = new FirefoxProfile();
    	//设置Firefox的“broswer.download.folderList”属性为2
    	/**
    	 * 如果没有进行设定,则使用默认值 1,表示下载文件保存在“下载”文件夹中
    	 * 设定为0,则下载文件会被保存在用户的桌面上
    	 * 设定为2,则下载的文件会被保存的用户指定的文件夹中
    	 */
    	profile.setPreference("browser.download.folderList", 2);
    	
    	//browser.download.manager.showWhenStarting的属性默认值为true
    	//设定为 true , 则在用户启动下载时显示Firefox浏览器的文件下载窗口
    	//设定为false,则在用户启动下载时不显示Firefox浏览器的文件下载窗口
    	profile.setPreference("browser.download.manager.showWhenStarting", false);
    	//设定文件保存的目录
    	profile.setPreference("browser.download.dir", downloadFilePath);
    	//browser.helperApps.neverAsk.openFile 表示直接打开下载文件,不显示确认框
    	//默认值.exe类型的文件,"application/excel"表示Excel类型的文件
    	
    	//	application/x-msdownload
    	profile.setPreference("browser.helperApps.neverAsk.openFile", "application/x-msdownload");
    	//browser.helperApps.never.saveToDisk 设置是否直接保存 下载文件到磁盘中默认值为空字符串,厦航代码行设定了多种温江的MIME类型
    	profile.setPreference("browser.helperApps.neverAsk.saveToDisk", "application/x-msdownload");
    	
    	//browser.helperApps.alwaysAsk.force 针对位置的MIME类型文件会弹出窗口让用户处理,默认值为true ,设定为false 表示不会记录打开未知MIME类型文件
    	profile.setPreference("browser.helperApps.alwaysAsk.force", true);
    	
    	//下载.exe文件弹出窗口警告,默认值是true ,设定为false 则不会弹出警告框
    	profile.setPreference("browser.download.manager.alertOnEXEOpen", false);
    	
    	//browser.download.manager.focusWhenStarting设定下载框在下载时会获取焦点
    	profile.setPreference("browser.download.manager.focusWhenStarting", true);
    		
    	//browser.download.manager.useWindow 设定下载是否现在下载框,默认值为true,设定为false 会把下载框隐藏
    	profile.setPreference("browser.download.manager.useWindow", false);
    	
    	//browser.download.manager.showAlertOnComplete 设定下载文件结束后是否显示下载完成的提示框,默认值为true,
    	//设定为false表示下载完成后,现在下载完成提示框
    	profile.setPreference("browser.download.manager.showAlertOnComplete", false);
    	
    	//browser.download.manager.closeWhenDone 设定下载结束后是否自动关闭下载框,默认值为true 设定为false 表示不关闭下载管理器
    	profile.setPreference("browser.download.manager.closeWhenDone", false);
    

    增加参考文章:https://www.cnblogs.com/wpjamer/articles/3873769.html

    2020.08.17

    常见异常

    下面记录几个java关于selenium的异常:

    
    /**未配置系统变量,即chromedriver.exe的位置
     * 配置方法如下:(最上面有详细的说明)
     * chrome:
     * System.setProperty("webdriver.chrome.driver", "chromedriver.exe的位置");
     * firefox:
     * System.setProperty("webdriver.gecko.driver", "geckodriver.exe的位置");
     * phantomjs:
     * System.setProperty("phantomjs.binary.path", "phantomjs.exe的位置");
     */
    java.lang.IllegalStateException: The path to the driver executable must be set by the webdriver.chrome.driver system property;
    
     
     /**
     * 这个出现的情况有很多,举个例子,如果你使用driver.get("www.baidu.com");就会出现这个报错,因为这个地址不对,要使用https://www.baidu.com这个完整路径。
     */
    org.openqa.selenium.InvalidArgumentException: invalid argument
    
    
    /**
     * 这个是比较常见的错误,比如打开百度首页后,直接
     * driver.findElements(By.id("testest"));
     * 就会报这个错误,因为页面上没有这个元素。
     * 首先反思一下选择器有没有写错,浏览器console先试试能不能拿到对应的元素,浏览器能拿到,但是selenium拿不到的话,
     * 看一下是不是元素在iframe内,在iframe的情况,selenium是要切换句柄的。
     * 然后看一下是不是页面或者元素需要某个操作(比如点击)才会出现,或者你刚点击,元素还没加载出来就开始获取了。
     * 还有  不要直接获取这个元素。
     * 正确的做法是:先判断有没有这个元素,如果没有,执行没有的逻辑(等待,刷新,或者抛出异常等等)
     * 一般来说,在获取这个元素之前,都会先用
     * new WebDriverWait(driver, 5).until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(cssSelector)));
     * 这个方法的意思是5秒内元素不出来就不往下走,5秒后还没出来就抛出异常
     */
    org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":"xxx"}
    
    
    /**
     * 要点击或者操作的元素已经不在当前页面的环境内了,例如打开一个网站后,获取了一个select下的option列表
     * 循环点击这个option列表,但是每点击一次,页面就会跳转到新的页面,那么在第二次循环的时候就会报这个异常,也就是说,你要操作的元素是你上一个页面的(或者已经消失的)元素,你在这个页面想点击一个不存在,但是你恰好还有WebElement实例的元素,就会报这个错。
     */
    org.openqa.selenium.StaleElementReferenceException: stale element reference: element is not attached to the page document
    
    
    /**
     * 当前元素不可交互,比如说,点击的元素不在页面可见范围内,如果是点击操作,可能点击上方还有别的元素挡住        
     * 了,也可能是当前元素不可点击。或者给一个disabled属性的input进行sendKeys操作。
     * 一般来说,点击都是通过执行js来实现的,但是执行js不一定能真正点击(具体原因还不清楚),sendKeys有时候会比执行js来的好用。
     */
    org.openqa.selenium.ElementNotInteractableException: element not interactable
    
     /**
     * 类似这种报错,有几种情况,用户文件夹被占用,chrome版本和chromedriver版本对不上
     */
    org.openqa.selenium.InvalidArgumentException: invalid argument: user data directory is already in use, please specify a unique value for --user-data-dir argument, or don't use --user-data-dir
    remote stacktrace: Backtrace:
    	Ordinal0 [0x007FC013+3194899]
    	Ordinal0 [0x006E6021+2056225]
    	Ordinal0 [0x0057F608+587272]
    	Ordinal0 [0x004FF28A+62090]
    	Ordinal0 [0x004FC64A+50762]
    	Ordinal0 [0x00521EE9+204521]
    	Ordinal0 [0x00521D0D+204045]
    	Ordinal0 [0x0051FC1B+195611]
    	Ordinal0 [0x00503B7F+80767]
    	Ordinal0 [0x00504B4E+84814]
    	Ordinal0 [0x00504AD9+84697]
    	Ordinal0 [0x006FCE64+2149988]
    	GetHandleVerifier [0x0096BE95+1400773]
    	GetHandleVerifier [0x0096BB61+1399953]
    	GetHandleVerifier [0x009731FA+1430314]
    	GetHandleVerifier [0x0096C69F+1402831]
    	Ordinal0 [0x006F3D61+2112865]
    	Ordinal0 [0x006FE5CB+2155979]
    	Ordinal0 [0x006FE6F5+2156277]
    	Ordinal0 [0x0070F26E+2224750]
    	BaseThreadInitThunk [0x76A56359+25]
    	RtlGetAppContainerNamedObjectPath [0x77127C24+228]
    	RtlGetAppContainerNamedObjectPath [0x77127BF4+180]
    
    

    常见方法(工具方法)

    划到页面底部

    System.setProperty("webdriver.chrome.driver", "E://drivers//chromedriver.exe");
    WebDriver driver = null;
    try {
        driver = new ChromeDriver();
        driver.get("https://blog.csdn.net/weixin_42525191/article/details/105216417");
        Actions actions = new Actions(driver);
        Thread.sleep(2000);
        //看效果记得打断点。
        actions.sendKeys(Keys.END).perform(); //方法一
        Thread.sleep(2000);
        ((JavascriptExecutor) driver).executeScript("window.scrollTo(0,document.body.scrollHeight)");//方法二
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        if(null!=driver){
            driver.quit();
        }
    }
    

    工具方法(java)。使用时,需要用到该工具类的方法直接继承该工具类即可

    import org.apache.commons.codec.binary.Base64;
    import org.apache.commons.lang3.ObjectUtils;
    import org.apache.commons.lang3.StringUtils;
    import org.openqa.selenium.*;
    import org.openqa.selenium.interactions.Actions;
    import org.openqa.selenium.remote.*;
    import org.openqa.selenium.remote.http.W3CHttpCommandCodec;
    import org.openqa.selenium.remote.http.W3CHttpResponseCodec;
    import org.openqa.selenium.support.ui.ExpectedConditions;
    import org.openqa.selenium.support.ui.WebDriverWait;
    
    import javax.imageio.ImageIO;
    import java.awt.image.BufferedImage;
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.lang.reflect.Field;
    import java.net.URL;
    import java.util.Collections;
    import java.util.List;
    
    /**
     * selenium 工具方法
     */
    public class WebDriverUtils {
    
        /**
         * 等待元素出现时间
         */
        private static final long WAIT_TIME_SECONDS = 5;
    
        /**
         * 延迟按键的基本睡眠时间
         */
        private static final Long SLEEP_TIME = 100L;
    
        /**
         * 延迟按键的随机睡眠时间
         */
        private static final Long SLEEP_RANDOM_TIME = 100L;
        
        /**
         * 用css选择option
         * @param driver 驱动
         * @param cssSelector css选择器
         * @param value 值
         * @return 返回执行结果
         */
        public static Object setValueByCssSelector(WebDriver driver, String cssSelector, String value) {
            String varName = "current_ele_" + System.currentTimeMillis();
            String script = "var " + varName + " = document.querySelector('" + cssSelector + "');" + varName + ".value='"
                    + value + "';" + varName + ".dispatchEvent(new UIEvent('change'));" + varName
                    + ".dispatchEvent(new InputEvent('input'));";
            return ((JavascriptExecutor) driver).executeScript(script);
        }
    
        /**
         * 获取单个元素
         * @param driver 元素
         * @param cssSelector css选择器
         * @return 返回元素
         */
        public static WebElement getEle(WebDriver driver, String cssSelector){
            if(null==driver || StringUtils.isEmpty(cssSelector)){
                throw new RuntimeException("驱动或者css选择为空");
            }
            try{
                new WebDriverWait(driver, WAIT_TIME_SECONDS).until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(cssSelector)));
                return driver.findElement(By.cssSelector(cssSelector));
            }catch (Exception e){
                throw new RuntimeException(e);
            }
        }
    
        /**
         * 延迟按键
         * @param driver 驱动
         * @param cssSelector css选择器
         * @param keys 待输入文本
         */
        public static void sendKeys(WebDriver driver, String cssSelector, String keys){
            if(null == driver || StringUtils.isEmpty(cssSelector) || StringUtils.isEmpty(keys)){
                throw new RuntimeException("驱动或者css选择器,或者待输入值为空");
            }
            if(!judgeEle(driver, cssSelector)){
                throw new RuntimeException("元素不存在");
            }
            WebElement ele = getEle(driver, cssSelector);
            sendKeys(ele, keys);
        }
    
        /**
         * 延迟按键
         * @param ele 待输入元素
         * @param keys 待输入文本
         */
        public static void sendKeys(WebElement ele, String keys){
            if(null == ele || StringUtils.isEmpty(keys)){
                throw new RuntimeException("待输入元素为空,或者待输入值为空");
            }
            ele.clear();
            int length = keys.length();
            for (int i = 0; i < length; i++) {
                char tempChar = keys.charAt(i);
                ele.sendKeys(String.valueOf(tempChar));
                sleep((int)(Math.floor(Math.random()*SLEEP_RANDOM_TIME)+SLEEP_TIME));
            }
        }
    
        /**
         * 获取元素内部的元素
         * @param ele 元素
         * @param cssSelector css选择器
         * @return 返回元素
         */
        public static WebElement getEle(WebElement ele, String cssSelector){
            if(null==ele || StringUtils.isEmpty(cssSelector)){
                throw new RuntimeException("驱动或者css选择为空");
            }
            try{
                return ele.findElement(By.cssSelector(cssSelector));
            }catch (Exception e){
                throw new RuntimeException(e);
            }
        }
    
        /**
         * 获取元素列表
         * @param driver 驱动
         * @param cssSelector css选择器
         * @return 返回元素列表
         */
        public static List<WebElement> getElements(WebDriver driver, String cssSelector){
            if(null==driver || StringUtils.isEmpty(cssSelector)){
                throw new RuntimeException("驱动或者css选择为空");
            }
            try{
                new WebDriverWait(driver, WAIT_TIME_SECONDS).until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(cssSelector)));
                return driver.findElements(By.cssSelector(cssSelector));
            }catch (Exception e){
                throw new RuntimeException(e);
            }
        }
    
        /**
         * 获取元素内部的元素列表
         * @param element 元素
         * @param cssSelector css选择器
         * @return 返回元素列表
         */
        public static List<WebElement> getElements(WebElement element, String cssSelector){
            if(null==element || StringUtils.isEmpty(cssSelector)){
                throw new RuntimeException("元素或者css选择为空");
            }
            try{
                return element.findElements(By.cssSelector(cssSelector));
            }catch (Exception e){
                throw new RuntimeException(e);
            }
        }
    
    
        /**
         * 根据css选择器单击元素
         * @param driver 驱动
         * @param cssSelector css选择器
         * @return 返回是否点击成功
         */
        public static boolean clickEle(WebDriver driver, String cssSelector){
            if(null==driver || StringUtils.isEmpty(cssSelector)){
                return false;
            }
            try{
                new WebDriverWait(driver, WAIT_TIME_SECONDS).until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(cssSelector)));
                ((JavascriptExecutor)driver).executeScript("arguments[0].click()", driver.findElement(By.cssSelector(cssSelector)));
            }catch (Exception e){
                e.printStackTrace();
                return false;
            }
            return true;
        }
    
        /**
         * 根据元素单击元素
         * @param driver 驱动
         * @param ele 元素
         * @return 返回是否点击成功
         */
        public static boolean clickEle(WebDriver driver, WebElement ele){
            if(null == driver || null==ele){
                return false;
            }
            try{
                ((JavascriptExecutor)driver).executeScript("arguments[0].click()", ele);
            }catch (Exception e){
                e.printStackTrace();
                return false;
            }
            return true;
        }
    
        /**
         * 根据css选择器双击元素
         * @param driver 驱动
         * @param cssSelector css选择器
         * @return 返回是否点击成功
         */
        public static boolean doubleClickEle(WebDriver driver, String cssSelector){
            if(null==driver || StringUtils.isEmpty(cssSelector)){
                return false;
            }
            try{
                new WebDriverWait(driver, WAIT_TIME_SECONDS).until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(cssSelector)));
                Actions actions = new Actions(driver);
                actions.doubleClick(driver.findElement(By.cssSelector(cssSelector))).perform();
            }catch (Exception e){
                e.printStackTrace();
                return false;
            }
            return true;
        }
    
        /**
         * 根据元素双击元素
         * @param driver 驱动
         * @param element 元素
         * @return 返回是否点击成功
         */
        public static boolean doubleClickEle(WebDriver driver, WebElement element){
            if(null==driver || null == element){
                return false;
            }
            try{
                Actions actions = new Actions(driver);
                actions.doubleClick(element).perform();
            }catch (Exception e){
                e.printStackTrace();
                return false;
            }
            return true;
        }
    
        /**
         * 判断元素是否存在,传驱动
         * @param driver 驱动
         * @param cssSelector css选择器
         * @return 返回是否存在
         */
        public static boolean judgeEle(WebDriver driver, String cssSelector){
            if(null==driver || StringUtils.isEmpty(cssSelector)){
                return false;
            }
            try{
                new WebDriverWait(driver, 2*WAIT_TIME_SECONDS).until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(cssSelector)));
            }catch (Exception e){
                return false;
            }
            return true;
        }
    
        /**
         * 判断元素内部是否存在某元素
         * @param ele 元素
         * @param cssSelector css选择器
         * @return 返回是否存在
         */
        public static boolean judgeEle(WebElement ele, String cssSelector){
            if(null==ele || StringUtils.isEmpty(cssSelector)){
                return false;
            }
            try{
                ele.findElement(By.cssSelector(cssSelector));
                return true;
            }catch (Exception e){
                return false;
            }
        }
    
        /**
         * 根据document.readyState 判断页面是否加载完成
         *
         * @param driver 驱动
         */
        public static boolean judgePageIsComplete(WebDriver driver) {
            if (null == driver) {
                throw new RuntimeException("驱动为空");
            }
            while (true) {
                try {
                    String isComplete = ((JavascriptExecutor) driver).executeScript("return document.readyState").toString();
                    if ("complete".equalsIgnoreCase(isComplete)) {
                        return true;
                    }
                    sleep(500L);
                } catch (Exception e) {
                    e.printStackTrace();
                    return false;
                }
            }
        }
    
        /**
         * 获取input的value
         * @param ele input
         * @return input的value属性
         */
        public static String getInputValue(WebElement ele){
            if(null==ele){
                return null;
            }
            return ele.getAttribute("value");
        }
    
        /**
         * 网页元素截图
         * @param driver 驱动
         * @param element 元素
         * @return 返回图片base64编码
         */
        public static String shotWebElement(WebDriver driver, WebElement element){
            if(null==driver||null==element){
                return null;
            }
            Point location = element.getLocation();
            Dimension size = element.getSize();
            ByteArrayOutputStream bos = null;
            String result = "";
            try {
                WebDriver augmentedDriver = new Augmenter().augment(driver);
                byte[] screenshotAs = ((TakesScreenshot) augmentedDriver).getScreenshotAs(OutputType.BYTES);
                BufferedImage originalImage = ImageIO.read(new ByteArrayInputStream(screenshotAs));
                BufferedImage croppedImage = originalImage.getSubimage(location.getX(), location.getY(), size.getWidth(), size.getHeight());
                bos = new ByteArrayOutputStream();
                ImageIO.write(croppedImage, "PNG", bos);
                result = Base64.encodeBase64String(bos.toByteArray()).replaceAll("\n", "");
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                if (null != bos) {
                    try {
                        bos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return result;
        }
    
    	/**
         * 根据sessionId 和 url 获取 driver
         * @param sessionId sessionId
         * @param url url
         * @return driver
         */
        public static RemoteWebDriver createDriverFromSession(final String sessionId, URL url){
            CommandExecutor executor = new HttpCommandExecutor(url) {
    
                @Override
                public Response execute(Command command) throws IOException {
                    Response response;
                    if ("newSession".equals(command.getName())) {
                        response = new Response();
                        response.setSessionId(sessionId);
                        response.setStatus(0);
                        response.setValue(Collections.<String, String>emptyMap());
                        try {
                            Field commandCodec = this.getClass().getSuperclass().getDeclaredField("commandCodec");
                            commandCodec.setAccessible(true);
                            commandCodec.set(this, new W3CHttpCommandCodec());
                            Field responseCodec = this.getClass().getSuperclass().getDeclaredField("responseCodec");
                            responseCodec.setAccessible(true);
                            responseCodec.set(this, new W3CHttpResponseCodec());
                        } catch (NoSuchFieldException | IllegalAccessException e) {
                            e.printStackTrace();
                        }
    
                    } else {
                        response = super.execute(command);
                    }
                    return response;
                }
            };
            return new RemoteWebDriver(executor, new DesiredCapabilities());
        }
    
        /**
         * 睡眠
         * @param time 睡眠时间/ms
         */
        private static void sleep(long time){
            try {
                Thread.sleep(time);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    
    
    }
    
    

    2020.09.17

    qq群:330405140(selenium学习之路),非教育非推销,单纯的测试技术群(主要是selenium)。
    群里有各种 小姐姐 解答问题,当然 小姐姐没看到问题就没办法了 -_-

    2020.09.21 (记一次火狐主页绑定 ~ 因为360)

    今天碰到一个很恶心的绑定主页,记录一下,火狐浏览器一直打开都很正常,今天打开突然指向了
    http://upan.000g.com (会重定向到360主页,别在浏览器打开)
    尝试了网上的一些办法,甚至重装了好几次火狐浏览器,结果再打开还是这个主页地址。这里说一下我的解决方法,由于我是安装在虚拟机上的firefox,虚拟机上安装有360,打开360,点击功能大全,找到主页防护,点一下,解锁所有的浏览器主页绑定,然后把浏览器主页设置为你想要的页面即可。

    2020.09.22 (记一次火狐记住密码不自动填写)

    手动打开火狐 about:preferences 进入隐私与安全,找到 登录信息与密码 除了使用主密码以外全勾上以后,关闭火狐,再打开查看配置,勾被取消了。
    如此一来,就算配置用户文件夹 user-data-dir,也没自动填写密码。
    我的做法是,打开表单页面,判断是否自动填写,若没有,则进入 about:preferences 页面,点击相应的按钮。java代码如下(参考上面的工具方法):

    WebElement email = getEle(driver, "#ap_email");
    if(StringUtils.isEmpty(email.getAttribute("value"))){
    	//进入火狐密码设置页面
        driver.get("about:preferences#privacy");
        //点击 向您询问是否保存网站的登录名和密码(R)
        if(judgeEle(driver, "#savePasswords")){
            clickEle(driver, "#savePasswords");
            sleep(1000L);
        }
        //点击 自动填写登录名和密码(I)
        if(judgeEle(driver, "#passwordAutofillCheckbox")){
            clickEle(driver, "#passwordAutofillCheckbox");
        }
        //返回表单填写页面
        driver.get(loginUrl);
        //判断页面是否加载完
        if (!judgePageIsComplete(driver)) {
            throw new RuntimeException("页面加载异常");
        }
    }
    

    注意,勾选之后返回之前的页面,页面是有刷新的,如果要开新窗口设置相关参数,返回原窗口的时候要刷新。

    2020.09.27(记如何拦截selenium请求)

    在看下面的方法之前,首先思考一下你是否需要这么做

    这里先问几个问题。
    第一,拦截selenium请求的原因是否是因为页面上的元素不是固定,不能直接通过元素选择器获取,需要解析请求的响应体来获取数据?

    第二,是否是因为需要新增请求头或者修改没有加密或很好解决的加密的请求参数?

    第三,是否是因为解析页面太慢,需要直接获取请求来达到快速获取数据的目的?

    以上只是部分原因,如果是因为这样,考虑用别的方式解决问题。例如:自己构造请求,发送数据返回给程序提取页面源码,使用beautifulsoup4,jsoup来解析元素
    给出使用selenium发送请求的demo:

    function getData() {
        let x = '';
        $.ajax({
            url: "https://blog.csdn.net//phoenix/web/v1/article/like",
            type: "post",
            async: false,
            data: "articleId=105216417",
            success: function(result) {
                x = result;
            }
        })
        return x;
    }
    //将以上函数代码修改后压缩,给selenium执行js,js末尾加上return getData();
    
    //如果页面没有jquery
    function getData() {
        let url = "https://blog.csdn.net//phoenix/web/v1/article/like";
        let xhr = new XMLHttpRequest();
        //get
        xhr.open("get", url, false);
        xhr.send(url);
        //post
        xhr.open('post',url,false);
    //    xhr.send('要发送的数据,例如 e=2&b=1 没有就是空字符串')
    	xhr.send("articleId=105216417");
        let res = '';
        if (xhr.readyState == 4 && xhr.status == 200) {
            res = xhr.responseText
        }
        return res
    }
    //将以上函数代码修改后压缩,给selenium执行js,js末尾加上return getData();
    

    以下是拦截请求的部分代码,亲自试验过,似乎没法拿到响应体,网上有人通过其他方式拿到响应体,但是不完美,这里就不拿响应体了。想拿也不是没办法,拿到请求头,请求url,请求体,自己发送就好了。

    先给出浏览器插件的webRequest的部分方法:

    //这个方法能获取请求体
    chrome.webRequest.onBeforeRequest.addListener(function (details) {
    	console.info(details);
    	/**
         * 通过请求体details拿到的requestBody有两种格式,formData的就不说了
         * 这里说一下ArrayBuffer的转化方法:
         * decodeURIComponent(escape(String.fromCodePoint.apply(null, new Uint8Array(d.requestBody.raw[0].bytes))))
         */
    },{urls: ["<all_urls>"]}, ["blocking",'requestBody'])
    
    //这个方法能获取请求头
    chrome.webRequest.onResponseStarted.addListener(function(details){
        console.info(details);
        //给每个请求添加 test:test 请求头
        details.requestHeaders.push({"name":"test","value":"test"})
    	//如果要修改某个请求头,判断details.url,再循环改details.requestHeaders的属性就好了。
        return { requestHeaders: details.requestHeaders };;
    },{urls:["<all_urls>"]},["responseHeaders"])
    
    //这个是google官方插件User-Agent Switcher for Chrome的改变user agent的函数 replaceHeader
    
    // Given a UserAgent object, will replace the "User-Agent" header in the
    // map provided as requestHeaders.
    function replaceHeader(user_agent, requestHeaders) {
      if (!user_agent || !user_agent.ua_string)
        return requestHeaders;
      var newHeaders = [];
      for (var i = 0; i < requestHeaders.length; i++) {
        if (requestHeaders[i].name != "User-Agent") {
          newHeaders.push(requestHeaders[i]);
        } else {
          var new_value = requestHeaders[i].value;
          if (user_agent.ua_string != "")
            new_value = (user_agent.append_to_default_ua ? new_value + " " + user_agent.ua_string : user_agent.ua_string);
          newHeaders.push({"name"  : "User-Agent",
                           "value" : new_value});
        }
      }
      return newHeaders;
    }
    

    以下是 java demo(zipFile方法参考上面的 设置有认证的代理):

    /**
     * 根据demo自行修改
     * @return
     * @throws Exception
     */
    private static ChromeOptions setChromeIntercept() throws Exception{
        ChromeOptions options = new ChromeOptions();
        FileWriter fileWriter1 = null;
        FileWriter fileWriter2 = null;
        String driverPath = "C:/";//浏览器插件存放文件目录
        String jsonFilePath = driverPath + "manifest.json";
        String jsFilePath = driverPath + "background.js";
        String zipFilePath = driverPath + "intercept.zip";
        File jsonFile = new File(jsonFilePath);
        File zipFile = new File(zipFilePath);
        File jsFile = new File(jsFilePath);
        try {
            String js = "chrome.webRequest.onBeforeSendHeaders.addListener(function(details){details.requestHeaders.push({\"name\":\"test\",\"value\":\"test\"});return{requestHeaders:details.requestHeaders}},{urls:[\"<all_urls>\"]},[\"blocking\",\"requestHeaders\"]);";
            String json = "{\"version\":\"1.0.0\",\"manifest_version\":2,\"name\":\"Chrome Intercept\",\"permissions\":[\"tabs\",\"unlimitedStorage\",\"storage\",\"<all_urls>\",\"webRequest\",\"webRequestBlocking\"],\"background\":{\"scripts\":[\"js/background.js\"]},\"minimum_chrome_version\":\"22.0.0\"}";
            if(!jsFile.exists()){
                jsFile.createNewFile();
            }
            if(!jsonFile.exists()){
                jsonFile.createNewFile();
            }
            fileWriter1 = new FileWriter(jsFilePath);
            fileWriter2 = new FileWriter(jsonFilePath);
            fileWriter1.write(js);
            fileWriter2.write(json);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try{
                if(null!=fileWriter1){
                    fileWriter1.flush();
                    fileWriter1.close();
                }
                if(null!=fileWriter2){
                    fileWriter2.flush();
                    fileWriter2.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        try {
            File[] files = new File[]{jsFile, jsonFile};
            //zipFile方法参考上面的 设置有认证的代理。
            zipFile(files, zipFile);
            options.addExtensions(zipFile);
        }catch (Exception e){
            e.printStackTrace();
        }
        return options;
    }
    

    这个是生成的文件结构目录:
    在这里插入图片描述

    群里有人说还有通过代理的方式拦截请求,具体去问群里的其他人吧。

    2020.11.02(记连接远程selenium)

    tips:远程连接火狐的时候,用户文件夹似乎不能设置。尝试了几种办法,最后发现他是把文件夹内容发送出去了,远程服务器接收到以后也没有打开火狐。似乎是有点问题。chrome配置用户文件夹是传地址,所以chrome可以远程配置用户文件夹。
    下面是步骤:

    1. 首先下载jar包:https://www.selenium.dev/downloads/
      下载最新稳定版本(Latest stable version)。

    2. 远程服务器上安装java环境,并配置环境变量,将jar包放入远程服务器上,将chromedriver的目录写入环境变量。

    3. 在jar包所在的文件夹打开命令行,输入

      java -jar xxxxxx.jar -port 8888
      

      xxx.jar 是你下载的jar包 , 8888 是你指定打开程序的端口,可以自己设置,如果看到打印

       Selenium Server is up and running on port 8888
      

      ,在本地尝试打开 http://服务器ip:8888/wd/hub/注意开放端口
      在这里插入图片描述

    如上图所示,则启动成功。

    1. 远程服务器jar包启动成功后,编写代码连接远程服务器,为远程打开selenium添加参数:

      @Test
      public void RemoteTest() throws Exception{
      	DesiredCapabilities chrome = DesiredCapabilities.chrome();
      	ChromeOptions options = new ChromeOptions();
      	options.addArguments("xxx参数");
      	chrome.merge(options);
      	chrome.setCapability("key","value");
      	WebDriver driver = null;
      	try{
      		driver = new RemoteWebDriver(new URL("http://远程ip:8888/wd/hub/"),chrome);
      		driver.get("https://www.baidu.com/s?wd=selenium")
      		Thread.sleep(2000L);
      	}catch(Exception e){
      		e.printStackTrace();
      	}finally{
      		if(null!=driver){
      			driver.quit();
      		}
      	}
      }
      
      

    tips:当需要为远程机器的 file inupt框sendkeys本地文件时,在初始化RemoteWebdriver后要加上:

    RemoteWebDriver driver = new RemoteWebDriver(new URL("http://ip:port/wd/hub"), caps);
    driver.setFileDetector(new LocalFileDetector());
    

    2021.04.12(记selenium跨域问题)

    首先说方法,如果不考虑环境安全性,可以直接使用参数:

    options.addArguments("--disable-web-security");
    

    使用这个参数打开的chrome,浏览器不会考虑跨域问题。
    在这里插入图片描述

    正常情况下,直接加上上面那个参数就好了,如果考虑环境安全,还是用别的方式。因为referer并没有变化,从百度出去的,referer就是百度。

    2021.04.26(记selenium的sessionId能干的事)

    首先要明确selenium grid的工作原理。它是服务端调用客户端的方式,服务端通过给客户端发送指令来控制客户端操作浏览器,通过阅读它的源码,抓包等方式,可以知道它其实是通过http请求来通信的。

    下面是一些模拟服务端给客户端发送消息操控客户端浏览器的请求示例。

    注意! !!!如果是grid的形式,则链接里包含/wd/hub,如果是本地,则没有!!!

    退出 相当于quit()

    服务关了,但是驱动没有退出怎么办?
    长久以来的问题,终于能解决了。我目前的方法是,驱动初始化后,记录驱动的sessionId(最好是持久化到数据库或者文件),当程序异常停止(或者运行的时候手动停止),通过获取之前记录的sessionId的方式关闭驱动(就算驱动已经关闭,也不会有什么影响)

    通过请求的方式创建selenium。方法如下,注意是delete方式

    DELETE  http://ip:port/wd/hub/session/sessionId
    

    在这里插入图片描述

    创建,打开浏览器

    通过请求的方式创建selenium。方法如下:

    POST  http://ip:port/wd/hub/session
    content-type: application/json
    

    请求体示例:

    {
      "desiredCapabilities": {
        "browserName": "chrome",
        "sessionId": "9d9cbf48ab3b0afe67afa63c143ee692",
        "goog:chromeOptions": {
          "args": [
          ],
          "extensions": [
          ]
        }
      },
      "capabilities": {
        "firstMatch": [
          {
            "browserName": "chrome",
            "goog:chromeOptions": {
              "args": [
              ],
              "extensions": [
              ]
            }
          }
        ]
      }
    }
    

    在这里插入图片描述
    tips:
    1.请求体具体参数属性可以在 ProtocolHandshake 类,createSession 方法里打断点,观察payload属性,通过构造不同的参数来确定json的格式
    2.sessionId已它返回的sessionId为准

    在这里插入图片描述

    获取元素

    获取元素信息(grid有/wd/hub,本地没有,此处演示是本地)

    POST	/session/0ccdfc35e328efb5592371d18938a57c/element
    Content-Type	application/json; charset=utf-8
    

    请求体示例:
    在这里插入图片描述

    tips:
    请求体可以在 AbstractHttpCommandCodec类,encode方法里打断点,观察this.json.toJson(parameters);的结果

    在这里插入图片描述

    获取元素文本

    获取元素文本(grid有/wd/hub,本地没有,此处演示是本地)

    GET		/session/0ccdfc35e328efb5592371d18938a57c/element/元素ID/text
    

    请求示例:
    在这里插入图片描述

    根据sessionId接管已经被selenium打开的浏览器 java版本(包你满意)

    之前一直说不可以,今天google的时候偶然看到了一个可行的办法。先上代码。操作方法写在注释里。

    import org.openqa.selenium.chrome.ChromeOptions;
    import org.openqa.selenium.remote.*;
    import org.openqa.selenium.remote.http.HttpClient;
    import org.openqa.selenium.remote.http.W3CHttpCommandCodec;
    import org.openqa.selenium.remote.http.W3CHttpResponseCodec;
    
    import java.io.IOException;
    import java.lang.reflect.Field;
    import java.net.URL;
    import java.util.Collections;
    import java.util.Map;
    
    /**
     * @author admin
     * 2021-06-22 13:51
     */
    
    public class SimpleWebDriver{
        
        public static RemoteWebDriver createDriverFromSession(final String sessionId, URL url){
            CommandExecutor executor = new HttpCommandExecutor(url) {
    
                @Override
                public Response execute(Command command) throws IOException {
                    Response response;
                    if ("newSession".equals(command.getName())) {
                        response = new Response();
                        response.setSessionId(sessionId);
                        response.setStatus(0);
                        response.setValue(Collections.<String, String>emptyMap());
                        try {
                            Field commandCodec;
                            commandCodec = this.getClass().getSuperclass().getDeclaredField("commandCodec");
                            commandCodec.setAccessible(true);
                            commandCodec.set(this, new W3CHttpCommandCodec());
                            Field responseCodec;
                            responseCodec = this.getClass().getSuperclass().getDeclaredField("responseCodec");
                            responseCodec.setAccessible(true);
                            responseCodec.set(this, new W3CHttpResponseCodec());
                        } catch (NoSuchFieldException | IllegalAccessException e) {
                            e.printStackTrace();
                        }
    
                    } else {
                        response = super.execute(command);
                    }
                    return response;
                }
            };
            return new RemoteWebDriver(executor, new DesiredCapabilities());
        }
    
    	//测试用
    	public static void main(String [] args) throws Exception{
            //填驱动位置
            System.setProperty("webdriver.chrome.driver", "E:\\drivers\\chromedriver_win32 -- 91\\chromedriver.exe");
            RemoteWebDriver driver = null;
            try {
                //如果是本地,直接用new ChromeDriver(options);,火狐没试过。
                driver = new RemoteWebDriver(new URL("http://ip:port/wd/hub"), new ChromeOptions());
                driver.get("https://blog.csdn.net/weixin_42525191/article/details/105216417");
                HttpCommandExecutor executor = (HttpCommandExecutor) driver.getCommandExecutor();
                //这里如果是本地,端口是程序启动时的端口,如果是远程,直接是上面的 http://ip:port/wd/hub
                URL url = executor.getAddressOfRemoteServer();
                System.out.println("url:"+url.toString());
                //第一次打开时的sessionId
                String sessionId = driver.getSessionId().toString();
                System.out.println("sessionId:"+sessionId);
                //假设此时程序崩了。你可以手动记录sessionId,在此关掉程序,注释掉上述的几行代码,将sessionId写死,解开下面的4行代码,运行看看结果。
                //没有url的,url = new URL("上面打印的url.toString()");
                
                /*RemoteWebDriver driver2 = createDriverFromSession(sessionId, url);
                driver2.get("http://www.baidu.com");
                System.out.println(driver2.getSessionId());
                //打断点用
                System.out.println();*/
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                if(null != driver){
                    //为了测试接管能力,这里注释掉
    //                driver.quit();
                }
            }
        }
    }
    

    这里重写了 HttpCommandExecutor 这个类的excute方法(上述的创建新ChromeDriver和退出都在这个方法里),通过伪造newSession请求的响应来获取ChromeDriver,因为 commandCodec 和 responseCodec 这两个变量是私有的,所以通过反射获取这两个变量,伪造了一个响应对象。这个方法可以归到工具方法里。
    对比一下原方法:
    在这里插入图片描述

    2021.09.14

    上面说的那个群现在每天开车吹水,新创建了一个群

    704662142

    有兴趣的同学可以加入看看,现在还没人。

    展开全文
  • hibernate 常见异常

    2010-05-16 00:31:13
    hibernate 常见异常非常不错的,hibernate 常见异常非常不错的
  • Hadoop常见异常

    2012-02-03 00:08:16
    Hadoop常见异常,以及hadoop配置,等资料
  • JAVA中常见异常

    2020-08-31 14:06:54
    本文主要介绍了JAVA中的常见异常类。具有很好的参考价值,下面跟着小编一起来看下吧
  • JAVA常见异常解析

    2012-12-17 13:25:52
    JAVA常见异常解析
  • 华为一碰传常见异常问题及解决方案(超详细)

    万次阅读 多人点赞 2020-03-17 22:17:34
    华为一碰传常见异常问题及解决方案: 1.一碰传激活失败 2.一碰传连接失败 3.一碰传传文件失败(一直转圈、出现感叹号) 4.华为电脑管家提示"正在加载服务,请稍候...” 5.一碰连接后提示“硬件解码器工作异常...” 6....

    一、关于Huawei share一碰传

          自从Huawei share发布以来,经过了好几次的更迭,目前支持一碰连接、一碰传文件、一碰录屏、多屏协同、共享剪贴板、电脑、手机、平板互相拖拽传文件等诸多黑科技玩法。Huawei share、多屏协同作为华为软件生态中非常重要的一环,极大地解放了生产力。
          原先只能在华为/荣耀的手机、笔记本使用的黑科技,经过网上大佬的破解,现在非华为/荣耀笔记本、装有蓝牙、WiFi的台式机也可以用上了。网上关于破解Huawei share一碰传、DIY NFC标签的教程有很多,这里就不再纂述了。
          附上一个博主看过并认为不错的教程:作者zzzain46写的《用NFC贴纸DIY实现华为一碰传》
          下面主要讲的是使用多屏协同、华为一碰传时遇到的一些异常问题和对应的解决方案。

    本篇博客为帅气的小白在CSDN的首发原创博客,转载请注明出处,如果喜欢的话可以收藏点赞哦,谢谢!!

    二、常见问题及解决方案

       1.一碰传激活失败

    在这里插入图片描述
    出错原因:所构造的NFC标签字符串格式不对
    解决方法:检查所构造的NFC标签字符串格式是否正确并纠正,注意MAC地址中间是不能带小横杠和空格的
          【╳】错误格式:SN=5EKPM18320000397|MAC=98-54-1B-2E-68-77|MODELID=00000505
          【✓】正确格式:SN=5EKPM18320000397|MAC=98541B2E6877|MODELID=00000505
    此处的SN为华为电脑管家识别出的序列号,MAC为蓝牙的MAC地址,MODELID为笔记本型号 506对应MateBook X Pro 505对应MateBook D
    注意:此处的错误码不一样,出错原因也不一样,可尝试更换其他SN码、更换新的NFC标签、重新生成新的二维码扫码激活。

       2.一碰传连接失败

    在这里插入图片描述
    出错原因:1.破解文件util.dll的问题,注意伪装SN码和无需伪装SN码所用的dll不同!!!
                      2.伪装SN码失败,出现不能一碰连接却可能可以一碰传的现象

    解决方法:1.更换破解文件util.dll 百度云链接 提取码:f5f6
                      2.检查伪装SN码是否存在,注意是Seria1Number而不是SerialNumber,保存之后要重启电脑才能生效!!!

    创建伪SN码步骤:
    1、以管理员身份启动Windows PowerShell
    2、运行wbemtest
    3、勾选“启用所有特权”建立连接
    4、打开类win32_bios
    5、新建属性Seria1Number,非Null,填入5EKPM18320000397(也可更改为其他的)
    6、保存属性,保存对象这里是引用

    在这里插入图片描述
                      3.可尝试修改华为电脑管家中的本机名为所伪装的SN码

    在这里插入图片描述

       3.一碰传传文件失败(一直转圈、出现感叹号)

    在这里插入图片描述 在这里插入图片描述
    出错原因:1.Microsoft Wi-Fi Direct 虚拟适配器 被禁用
                      2.电脑蓝牙异常
    解决方法:1.右键win菜单打开设备管理器,启用被禁用的虚拟网卡
    在这里插入图片描述
                      2.右键win菜单打开设备管理器,先禁用蓝牙设备后重新启用
    注意:打开蓝牙时此处显示的设备过多,可以先关闭蓝牙再进行禁用。
    在这里插入图片描述
                      3.重启电脑或关闭蓝牙后重新打开
                      4.更新电脑的蓝牙和WiFi驱动

       4.华为电脑管家提示"正在加载服务,请稍候…”

    在这里插入图片描述
    出错原因:MBAMainService(Huawei PCManager Windows Service)服务未启动或被禁用
    解决方法:1.重启电脑 2.手动开启Huawei PCManager Windows Service服务
    在这里插入图片描述

       5.一碰连接后提示“硬件解码器工作异常…”

    在这里插入图片描述
    出错原因:显卡兼容性问题
    解决方法:1.重启电脑和手机后重新尝试连接
                      2.检查更新电脑显卡驱动
                      3.若电脑带集显和独显可尝试切换另一块显卡
                      4.手动降低手机的分辨率,1080P或720P

       6.华为电脑管家提示“手机与电脑连接已断开”

    在这里插入图片描述
    出错原因:连接后手机或电脑的蓝牙/WiFi被关闭导致连接断开
    解决方法:开启手机和电脑的蓝牙、WiFi后重新连接
    注意:NFC仅为建立连接或者是一碰传的时候使用,所以成功建立连接后关闭NFC并不会断开连接,但如果关闭蓝牙或者WiFi就不行啦。

       7.手机画面一直卡在正在连接…

    在这里插入图片描述
    出错原因:手机的蓝牙、WiFi、Huawei share以及电脑的蓝牙、WiFi未开启
    解决方法:手机开启NFC并触碰NFC标签后,手机的蓝牙、WiFi、Huawei share稍等一下会自动开启,不过电脑的蓝牙、WiFi就需要手动去开启啦,开启后重新触碰NFC标签即可正常弹窗建立连接。

       8.多屏协同不可用

    在这里插入图片描述
    出错原因:当前所用的手机或系统不支持多屏协同
    解决方法:更新华为电脑管家版本、更新手机系统、更换支持多屏协同的设备
    多屏协同目前仅支持EMUI10.0及以上,处理器为麒麟980及以上的华为/荣耀手机
    (现有部分麒麟970的手机也逐渐升级支持了多屏协同,如Mate10系列)

    三、参考资料

    华为一碰传官网介绍:https://consumer.huawei.com/cn/support/huaweishareonehop/
    用NFC贴纸DIY实现华为一碰传:https://www.52debug.cn/posts/183e4c43.html#more
    一碰传常见问题及解决方案:https://club.honor.cn/thread-20505636-1-1.html

    展开全文
  • 常见异常.txt

    2011-12-10 13:34:33
    常见异常.txt
  • 主要介绍了java程序常见异常及处理汇总,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • Java常见异常和错误.pdf
  • 常见异常及解决办法

    2013-11-25 22:20:42
    java常见异常及解决办法

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 490,076
精华内容 196,030
关键字:

常见异常