使用不同的ChromeDriver实例相同的镀铬轮廓(会话) [英] using the same chrome profile (session) for different ChromeDriver instances
问题描述
我想并行打开多个浏览器,但我不能浏览该网站在多个窗口。
I am trying to open multiple browsers in parallel, but I can not navigate to the website in more than one window..
下面是我如何做到这一点:
Here is how I do it:
namespace XXX
{
public class CoreDriver
{
public IWebDriver driver;
public int my_port { get; set; }
public void Initialize()
{
string chromeee = "";
if (my_port == 50147) { chromeee = "C:/Users/AA/Downloads/chromedriver1/"; }
else if (my_port == 50148) {chromeee = "C:/Users/AA/Downloads/chromedriver2/"; }
else if (my_port == 50149) { chromeee = "C:/Users/AA/Downloads/chromedriver3/"; }
else if (my_port == 50140) { chromeee = "C:/Users/AA/Downloads/chromedriver4/"; }
ChromeOptions options = new ChromeOptions();
options.AddArgument("user-data-dir=C:\\Users\\AA\\AppData\\Local\\Google\\Chrome\\User Data");
var driverService = ChromeDriverService.CreateDefaultService(chromeee);
driverService.HideCommandPromptWindow = true;
driverService.Port = my_port;
driver = new ChromeDriver(driverService, options);
driver.Manage().Timeouts().ImplicitlyWait(new TimeSpan(0,0,12));
driver.Manage().Timeouts().SetPageLoadTimeout(TimeSpan.FromSeconds(13));
//driver navigate
}
}
}
调用它,因为这:
CoreDriver A1 = new CoreDriver();
A1.my_port = 50147;
A1.Initialize();
CoreDriver A2 = new CoreDriver();
A2.my_port = 50148;
A2.Initialize(); // timeout error here
// ...
不幸的是,后打开第二个窗口 - 超时错误是shownn:
Unfortunately, after the second window is opened - timeout error is shownn:
型的第一个机会异常'OpenQA.Selenium.WebDriverException'
发生在WebDriver.dll
A first chance exception of type 'OpenQA.Selenium.WebDriverException' occurred in WebDriver.dll
附加信息:HTTP请求的URL为HTTP远程的webdriver
服务器:/ loca1host:50148 /会话后,60 $超时; b $ b秒
Additional information: The HTTP request to the remote WebDriver server for URL http:/loca1host:50148/session timed out after 60 seconds.
在这一行:
司机=新ChromeDriver(driverService,期权);
driver = new ChromeDriver(driverService, options);
重新运行使用不同的参数测试后,我发现了错误是由于显示在指定的Chrome个人资料:
after rerunning the test with different parameters I have found out that the error is shown due to the specified Chrome profile:
options.AddArgument("user-data-dir=C:\\Users\\AA\\AppData\\Local\\Google\\Chrome\\User
Data");
如果我删除行 - 那么我所有的饼干将不会在ChromeDriver情况下使用,这是不是,我可以:)
住有一种使用在多个chromedriver实例相同的镀铬轮廓的方法是什么?
If I remove the line - then all of my cookies will not be used in ChromeDriver instance and that is not something that I can live with :) Is there a way to use the same chrome profile in multiple chromedriver instances?
推荐答案
好了,所以我用我的方法如前所述
Okay, so I am using my approach as stated above.
我的要求是:
- 我必须保持主要的镀铬轮廓的饼干
- 我必须保持主配置文件的扩展名
- 我不需要历史上,现有的自定义配置文件的一个新的开始后,打开的标签页,主配置文件
- 的会议等等 - 我开始清楚没有打开的标签
- I must keep the cookies of the main chrome profile
- I must keep extensions of the main profile
- I do not need the history, opened tabs, session etc. of the main profile
- after a new start of an existing custom profile - i start it clear without opened tabs
下面是几句话的逻辑。
- 首先,我指定一个目录现有的谷歌浏览器的配置文件。
- 如果我们需要创建的cookie(即登录到某网站),那么我们做它在谷歌浏览器的主要轮廓。
- 它完成后,关闭浏览器。有些网站的Cookie保持很长一段时间,一些 - 不是。因此,它是符合我们的利益的主要轮廓重新登录,如果必要。不要保留原有的镀铬开了!否则ChromeDriver会抛出一些警告。
- 接下来,我的脚本将必需的文件夹和文件复制到新文件夹。此文件夹是我们与所有的cookies新的配置文件。一切都是关于 30兆字节在我的电脑上尺寸
- 如果新配置文件的文件夹已经存在 - 那么程序只会复制饼干文件。这是不应该超过 1-2兆数据。
- First I specify a directory for the existing Google Chrome profile.
- If we need to create cookies (i.e. login into some website) then we do it on the main profile of google chrome.
- After it is done, close the chrome. Some websites keep cookies for a long time, some - not. So it is in our interest to relogin on the main profile when necessary. Do not keep the Original chrome opened! Otherwise ChromeDriver will throw some warnings.
- Next, my script will copy the necessary folders and files into new folder. This folder is our new profile with all cookies. Everything is about 30 megabytes in size on my PC.
- If the folder for the new profile already exists - then the program will only copy cookies files. That's shouldn't be more than 1-2 megs of data.
和这里是代码。你可能需要调整一件事或另一个
And here is the code. You might want to tweak one thing or another.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Support.UI;
using OpenQA.Selenium.Internal;
using OpenQA.Selenium.Remote;
using System.IO;
using System.Drawing.Imaging;
using System.Management;
using System.Text.RegularExpressions;
using System.Threading;
using System.Diagnostics;
using System.Reflection;
using System.Threading.Tasks;
using System.Collections.Concurrent;
using System.Runtime.InteropServices;
using System.Net;
namespace NAMESPACE
{
public class CoreDriver
{
public IWebDriver driver;
public string my_name { get; set; }
public int my_port { get; set; }
public string default_profile_dir = @"C:\Users\USERNAME\AppData\Local\Google\Chrome\";
public string chromedriver_path = @"C:\Users\USERNAME\Downloads\chromedriver_win32\";
public string site_profile_path;
public string site_profile_path_s;
public string default_path;
public void Initialize()
{
ChromeOptions options = new ChromeOptions();
options.AddArgument("--log-level=3");
options.AddArgument("--test-type");
options.AddArgument("--silent");
options.AddArgument("user-data-dir=" + site_profile_path_s);
options.AddArgument("--disable-plugins"); // disable flash
var driverService = ChromeDriverService.CreateDefaultService(chromedriver_path);
driverService.HideCommandPromptWindow = true;
driverService.Port = my_port;
driver = new ChromeDriver(driverService, options);
driver.Manage().Timeouts().ImplicitlyWait(new TimeSpan(0, 0, 14));
driver.Manage().Timeouts().SetPageLoadTimeout(TimeSpan.FromSeconds(15));
IJavaScriptExecutor jscript = driver as IJavaScriptExecutor;
jscript.ExecuteScript("return window.stop");
}
public void ConfigureProfile()
{
site_profile_path_s = default_profile_dir + "profile " + my_name;
site_profile_path = site_profile_path_s + @"\Default";
default_path = default_profile_dir + @"User Data\Default";
if (!Directory.Exists(site_profile_path))
{
CreateBlankProfile();
}
else
{
// copy existing chrome profile. Keep cache, extensions, etc.
CopyProfileFiles();
// but stay away from opened tabs
RemoveOpenedTabsFiles();
}
}
public void CleanUpOldProfiles()
{
DirectoryInfo di = new DirectoryInfo(default_profile_dir);
DirectoryInfo[] directories = di.GetDirectories("profile*", SearchOption.TopDirectoryOnly);
if (directories.Count() > 0)
{
foreach (var folder in directories)
{
try
{
Directory.Delete(folder.FullName, true);
}
catch
{
}
}
}
}
public void CreateBlankProfile()
{
// new profile direftory
CreateIfMissing();
// copy existing chrome profile. Keep cache, extensions, etc.
// but stay away from opened tabs
CopyProfileFiles();
CopyProfileFolders();
}
public void CopyProfileFiles()
{
// default profile location
DirectoryInfo di = new DirectoryInfo(default_path);
// copy files
List<string> file_lib = new List<string>() { "Cookies", "Login", "Preferences", "Secur" };
FileInfo[] files = di.GetFiles("*", SearchOption.TopDirectoryOnly);
if (files.Count() > 0)
{
foreach (var file in files)
{
if (PassFileOrFolder(file.Name, file_lib))
{
file.CopyTo(site_profile_path + @"\" + file.Name, true);
}
}
}
}
public void RemoveOpenedTabsFiles()
{
// default profile location
DirectoryInfo di = new DirectoryInfo(site_profile_path);
// copy files
List<string> file_lib = new List<string>() { "Current", "Last" };
FileInfo[] files = di.GetFiles("*", SearchOption.TopDirectoryOnly);
if (files.Count() > 0)
{
foreach (var file in files)
{
if (PassFileOrFolder(file.Name, file_lib))
{
File.Delete(file.FullName);
}
}
}
}
public void CopyProfileFolders()
{
// default profile location
DirectoryInfo di = new DirectoryInfo(default_path);
// copy folders
List<string> folder_lib = new List<string>() { "databases", "Extension", " Storage", "Web Applications", "File System", "IndexedDB" };
DirectoryInfo[] directories = di.GetDirectories("*", SearchOption.TopDirectoryOnly);
if (directories.Count() > 0)
{
foreach (var folder in directories)
{
if (PassFileOrFolder(folder.Name, folder_lib))
{
DirectoryCopy(folder.FullName, site_profile_path + @"\" + folder.Name, true);
}
}
}
}
private void CreateIfMissing()
{
Directory.CreateDirectory(site_profile_path);
}
private static void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)
{
// Get the subdirectories for the specified directory.
DirectoryInfo dir = new DirectoryInfo(sourceDirName);
DirectoryInfo[] dirs = dir.GetDirectories();
if (!dir.Exists)
{
throw new DirectoryNotFoundException(
"Source directory does not exist or could not be found: "
+ sourceDirName);
}
// If the destination directory doesn't exist, create it.
if (!Directory.Exists(destDirName))
{
Directory.CreateDirectory(destDirName);
}
// Get the files in the directory and copy them to the new location.
FileInfo[] files = dir.GetFiles();
foreach (FileInfo file in files)
{
string temppath = Path.Combine(destDirName, file.Name);
file.CopyTo(temppath, false);
}
// If copying subdirectories, copy them and their contents to new location.
if (copySubDirs)
{
foreach (DirectoryInfo subdir in dirs)
{
string temppath = Path.Combine(destDirName, subdir.Name);
DirectoryCopy(subdir.FullName, temppath, copySubDirs);
}
}
}
public bool PassFileOrFolder(string input, List<string> library)
{
foreach (string name in library)
{
if (input.Contains(name))
{
return true;
}
}
return false;
}
}
}
请注意,我也有实施清理所有配置的方法 CleanUpOldProfiles
Please note that I have also implemented a method to clean up all profiles CleanUpOldProfiles
查看代码,更改目录等完成后 - 做下面的调用:
Review the code, make changes to directories etc. After done - make a following call:
CoreDriver something = new CoreDriver(); // creating an object
// settings
something.my_port = 50150; // multiple chrome instances - will be run on different ports
// I am currently having 4 chrome profiles ;)
something.my_name = "mynewprofile"; // full profile name will be: 'profile + my_name'. Check the code of the object.
// void
something.ConfigureProfile(); // creating new profile or updating existing one, if folder eists
something.Initialize(); // starting the browser
对不起了很长的答案。希望它可以帮助你们莫名其妙:)
sorry for a long answer. Hope it helps you guys somehow :)
这篇关于使用不同的ChromeDriver实例相同的镀铬轮廓(会话)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!