首页 > 解决方案 > 从一个 Selenium 会话到另一个会话长期保存 Cookie 的最佳方法?

问题描述

我正在使用Selenium WebDriver启动特定的 Firefox 配置文件。通常,Selenium 会创建一个临时安装的 FF,它模仿现有的 Firefox 配置文件,然后在调用webdriver.close().

但是,我需要能够Firefox WebDriver通过某些登录 cookie 启动Selenium并为将来的会话保留某些登录 cookie,这样我每次登录帐户时都不会被要求输入密码和/或验证码。我已经看到了一些解决这个问题的方法,但每种方法都有自己的问题:

1)识别Selenium创建的临时文件,复制cookies.sqlite到原来的FF Profile安装文件夹。我看到这种方法的问题是我同时启动了许多 Selenium 实例,那么我将如何确定哪个临时文件夹对应于特定的 WebDriver 会话?另外,是否可以将 cookie 附加到原始安装文件而不是覆盖原始文件?

2)一位用户建议致电:

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

在调用之前driver.close(),然后通过调用将 cookie 添加到下一个 WebDriver 会话:

for(Cookie cookie : allCookies)
{
    driver.manage().addCookie(cookie);
}

我看到这种方法的问题是我需要长期(即永远)保留 cookie,并且我无法将所有会话的 cookie 存储在内存中。即使可以,当程序存在或主机关闭时,cookie 数据也会丢失。此外,getCookies()仅返回当前域的 cookie,而 addCookie() 只允许添加域与当前 URL 的域相同的 cookie。因此,正如一位评论者指出的那样,在获取或设置 cookie 时,首先访问正确的 URL 很重要。我想在新的 FF 会话启动时立即从多个域加载 cookie。

3)另一种选择可能是首先阻止Firefox在新位置创建临时文件(即重定向到原始FF安装目录)并防止FF在退出时删除临时文件。这样的事情可行吗?

我见过其他一些方法,但它们要么仅解决与 Chrome(不是 Firefox)或 Python 相关的问题,要么遭受上述缺陷之一的困扰。

在 Java + Firefox 中可以使用什么方法来解决这个问题?

谢谢!

标签: javaseleniumselenium-webdriverfirefoxcookies

解决方案


对您来说最好的解决方案是当您想要存储它们以将您的 cookie 存储在 JSON 文件中时,这样您以后就可以在浏览器中加载它们。

这是如何存储它们的快速教程:TUTORIAL

用 JSON 编写:

import java.io.FileWriter;
import java.io.IOException;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;

public class WriteJSONExample
{
  @SuppressWarnings("unchecked")
  public static void main( String[] args )
{
    //First Employee
    JSONObject employeeDetails = new JSONObject();
    employeeDetails.put("firstName", "Lokesh");
    employeeDetails.put("lastName", "Gupta");
    employeeDetails.put("website", "howtodoinjava.com");
     
    JSONObject employeeObject = new JSONObject(); 
    employeeObject.put("employee", employeeDetails);
     
    //Second Employee
    JSONObject employeeDetails2 = new JSONObject();
    employeeDetails2.put("firstName", "Brian");
    employeeDetails2.put("lastName", "Schultz");
    employeeDetails2.put("website", "example.com");
     
    JSONObject employeeObject2 = new JSONObject(); 
    employeeObject2.put("employee", employeeDetails2);
     
    //Add employees to list
    JSONArray employeeList = new JSONArray();
    employeeList.add(employeeObject);
    employeeList.add(employeeObject2);
     
    //Write JSON file
    try (FileWriter file = new FileWriter("employees.json")) {
        //We can write any JSONArray or JSONObject instance to the file
        file.write(employeeList.toJSONString()); 
        file.flush();

    } catch (IOException e) {
        e.printStackTrace();
    }
}
}

读入 JSON:

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
 
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
 
public class ReadJSONExample 
{
    @SuppressWarnings("unchecked")
    public static void main(String[] args) 
    {
        //JSON parser object to parse read file
        JSONParser jsonParser = new JSONParser();
         
        try (FileReader reader = new FileReader("employees.json"))
        {
            //Read JSON file
            Object obj = jsonParser.parse(reader);
 
            JSONArray employeeList = (JSONArray) obj;
            System.out.println(employeeList);
             
            //Iterate over employee array
            employeeList.forEach( emp -> parseEmployeeObject( (JSONObject) emp ) );
 
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
 
    private static void parseEmployeeObject(JSONObject employee) 
    {
        //Get employee object within list
        JSONObject employeeObject = (JSONObject) employee.get("employee");
         
        //Get employee first name
        String firstName = (String) employeeObject.get("firstName");    
        System.out.println(firstName);
         
        //Get employee last name
        String lastName = (String) employeeObject.get("lastName");  
        System.out.println(lastName);
         
        //Get employee website name
        String website = (String) employeeObject.get("website");    
        System.out.println(website);
    }
}

推荐阅读