【问题标题】:How to get the webdriver object using just the session ID Or cookies of existing webdriver session如何仅使用现有 webdriver 会话的会话 ID 或 cookie 获取 webdriver 对象
【发布时间】:2020-01-03 16:43:23
【问题描述】:

我有一种情况,webdriver 对象隐藏在依赖项目的包装器中,我只能以字符串格式检索 会话 id 并从这些函数返回 driver.manage()/cookies。

现在我正在尝试使用此会话 ID 并将其传递给我的 webdriver 引用变量,以便我可以扩展我的要求。

我还找到了与以下相同的参考:

https://tarunlalwani.com/post/reusing-existing-browser-session-selenium-java/

我试过了,但出现如下错误:

线程“主”org.openqa.selenium.json.JsonException 中的异常: 无法从以下位置确定类型:

带有 cookie 的代码:

public static void main(String[] args) throws URISyntaxException, MalformedURLException {
    WebDriver driver = null;

    //WebDriverManager.chromedriver().setup();
    WebDriverManager.chromedriver().version(Configuration.getConfigurationValueForProperty("chrome-version"))
            .setup();
    ChromeOptions options = new ChromeOptions();
    options.addArguments("start-maximized");
    options.addArguments("enable-automation");
    // options.addArguments("--headless");
    options.addArguments("--no-sandbox");
    options.addArguments("--disable-infobars");
    options.addArguments("--disable-dev-shm-usage");
    options.addArguments("--disable-browser-side-navigation");
    options.addArguments("--disable-gpu");
    driver = new ChromeDriver(options);
    driver.get(Configuration.applicationUnderTestURL());

    Set<Cookie> name =driver.manage().getCookies();

    WebDriver driver3 = null;

    for(Cookie test: name) 
    {
        driver3.manage().addCookie(test);
    }

    driver3.get("https://stackoverflow.com/questions/8638241/setting-cookie-through-foreach-loop-inside-while-loop");

}

我尝试使用会话 ID 的演示代码:

package stepdef;

import java.io.IOException;
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Collections;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.Command;
import org.openqa.selenium.remote.CommandExecutor;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.HttpCommandExecutor;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.Response;
import org.openqa.selenium.remote.SessionId;
import org.openqa.selenium.remote.http.W3CHttpCommandCodec;
import org.openqa.selenium.remote.http.W3CHttpResponseCodec;

import automationframework.Configuration;
import io.github.bonigarcia.wdm.WebDriverManager;

public class testing {

public static void main(String[] args) throws URISyntaxException, MalformedURLException {
    WebDriver driver = null;

    //WebDriverManager.chromedriver().setup();
    WebDriverManager.chromedriver().version(Configuration.getConfigurationValueForProperty("chrome-version"))
            .setup();
    ChromeOptions options = new ChromeOptions();
    options.addArguments("start-maximized");
    options.addArguments("enable-automation");
    // options.addArguments("--headless");
    options.addArguments("--no-sandbox");
    options.addArguments("--disable-infobars");
    options.addArguments("--disable-dev-shm-usage");
    options.addArguments("--disable-browser-side-navigation");
    options.addArguments("--disable-gpu");
    driver = new ChromeDriver(options);
    driver.get(Configuration.applicationUnderTestURL());

    SessionId session = ((ChromeDriver)driver).getSessionId();

    String session2 = session.toString();

    System.out.println(session2);

    String str = "http://google.com"; // just passing random URL as I have only session id
    URI uri = new URI(str);
    URL url = uri.toURL();


    RemoteWebDriver driver2 = createDriverFromSession(session, url);    
    driver2.get("http://tarunlalwani.com"); // here I am getting error where I need to resue the existing browser using session id



}

public static RemoteWebDriver createDriverFromSession(final SessionId sessionId, URL command_executor){
    CommandExecutor executor = new HttpCommandExecutor(command_executor) {

    @Override
    public Response execute(Command command) throws IOException {
        Response response = null;
        if (command.getName() == "newSession") {
            response = new Response();
            response.setSessionId(sessionId.toString());
            response.setStatus(0);
            response.setValue(Collections.<String, String>emptyMap());

            try {
                Field commandCodec = null;
                commandCodec = this.getClass().getSuperclass().getDeclaredField("commandCodec");
                commandCodec.setAccessible(true);
                commandCodec.set(this, new W3CHttpCommandCodec());

                Field responseCodec = null;
                responseCodec = this.getClass().getSuperclass().getDeclaredField("responseCodec");
                responseCodec.setAccessible(true);
                responseCodec.set(this, new W3CHttpResponseCodec());
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }

        } else {
            response = super.execute(command);
        }
        return response;
    }
    };

    return new RemoteWebDriver(executor, new DesiredCapabilities());
}
}

请告诉我是否可能或任何方式

【问题讨论】:

  • 哪一行抛出异常?
  • driver2.get("tarunlalwani.com"); 这一行
  • 我也有 cookie .. 我也可以从现有 cookie 创建 Webdriver 引用吗?
  • 我想你可以。您可以创建一个 WebDriver 实例,然后加载现有的 cookie。从那里,您可能能够访问该网站,就像您使用与以前相同的浏览器一样。作为参考,this 已在 Python 中完成
  • 我也添加了该代码,但它抛出空错误

标签: java selenium selenium-webdriver selenium-chromedriver


【解决方案1】:

似乎尝试修改现有WebDriver 对象的Optionsnot possible。这意味着尝试修改现有 WebDriver 对象的 cookie 或会话 ID 也是不可能的。

那么,这里唯一的解决方法是创建一个新的WebDriver 实例。但是,创建一个新的 WebDriver 实例是 OP 设置的限制,因此这是不可行的。

【讨论】:

    【解决方案2】:

    假设您无权访问驱动程序实例,只能访问包装驱动程序的会话 ID。 在这里,我们将尝试将现有会话附加到新创建的实例。最终我们将退出这两个实例。

    扩展 RemoteWebDriver 类

    public class MyRemoteDriver extends RemoteWebDriver{
    
    public MyRemoteDriver(URL remoteAddress, Capabilities capabilities) {
        super(remoteAddress,capabilities);
      }
    
    @Override 
    public void setSessionId(String opaqueKey) {
        super.setSessionId(opaqueKey);
      }
    
    
    }
    

    现在测试:我们将使用 MyRemoteDriver 创建新实例并将现有会话附加到该实例。

    public class StackOverflow59566324 {
    
    @Test
    public void testing() {
        WebDriver driver = null;
        MyRemoteDriver mydriver = null;
    
        try {
    
            ChromeOptions option = new ChromeOptions();
    
            final URL url = new URL("http", "localhost", 4444, "/wd/hub");
    
            driver = new RemoteWebDriver(url, option);
            driver.get("https://www.google.com");
    
            mydriver = new MyRemoteDriver(url, option);
            mydriver.get("http://www.google.com");
    
           // store new session id 
            String newSession = mydriver.getSessionId().toString();
    
            // Set the session of wrapped driver here 
            mydriver.setSessionId(((RemoteWebDriver)driver).getSessionId().toString());  
    
            // Now we are controlling wrapped driver session using our own driver instance
            mydriver.get("http://www.bing.com");
            mydriver.manage().window().maximize();
    
            // Just to see the magic
            Thread.sleep(10000);
    
            //Quit the wrapped session 
            mydriver.quit();
    
            //Quit the new orphaned session which we are not using anyway 
            mydriver.setSessionId(newSession);
            mydriver.quit();
    
        }        
        catch(Exception e) {          
            System.out.println(e.getMessage());          
            mydriver.quit();           
        }
    }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2021-10-25
      • 1970-01-01
      • 2013-10-22
      • 1970-01-01
      • 2015-12-14
      • 1970-01-01
      • 1970-01-01
      • 2019-09-23
      • 2012-02-02
      相关资源
      最近更新 更多