selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 77
我必须手动更新书面脚本中的chrome驱动程序。有什么方法可以使用更新的chrome版本自动更新它吗?
#1 楼
尝试从npm使用webdriver-manager:https://www.npmjs.com/package/webdriver-manager
,然后使用Java,Python中的批处理文件调用
webdriver-manager update
或任何一种工具。 要创建批处理文件,请打开一个文本文件并添加
webdriver-manager update
作为内容,然后将其另存为file.bat #2 楼
是的,可以做到。您需要执行以下步骤,并且需要选择一种用于实现它们的工具。让我们看一下Python中的几行内容,我将概述主要流程,并且您可能希望对其进行更多构建功能强大(例如命令行参数等)。
首先,我将导入
requests
: import requests
然后我将将必要的链接保存到两个变量中+我定义了所需版本的chrome驱动程序的文件名:
url = 'https://chromedriver.storage.googleapis.com/LATEST_RELEASE_'
url_file = 'https://chromedriver.storage.googleapis.com/'
file_name = 'chromedriver_linux64.zip'
现在我' ll让用户选择一个版本,然后从网站上获取该版本:
version = input()
version_response = requests.get(url + version)
最后,是时候下载zip文件(如果存在):
if version_response.text:
file = requests.get(url_file + version_response.text + '/' + file_name)
with open(file_name, "wb") as code:
code.write(file.content)
这些步骤的结果将是一个带有chrome驱动程序的zip文件。当前目录(运行脚本的位置)。成功下载后,还可以使用
zipfile
库提取zip文件。如果要完全自动化,则可能需要内置命令行参数并将chrome版本通过管道传递到Python脚本中。例如。在类似Arch的系统中,您可以使用
$ pacman -Qs chromium
获得Chromium版本。由于您没有提到要在其上构建的系统体系结构,因此我选择了我的系统。准备好后,可以让它与
cron
或类似的软件一起运行。#3 楼
使用WebdriverManage。它将所需的驱动程序二进制文件(如果本地不存在)下载到缓存(默认位置〜/ .m2 / repository / webdriver)中。这是将其添加到代码中的方法:WebDriverManager.chromedriver().setup();
WebDriver driver = new ChromeDriver();
最新版本依赖项:
<!-- https://mvnrepository.com/artifact/io.github.bonigarcia/webdrivermanager -->
<dependency>
<groupId>io.github.bonigarcia</groupId>
<artifactId>webdrivermanager</artifactId>
<version>3.7.1</version>
</dependency>
#4 楼
一种适用于您要自动化的任何编程语言的解决方案。这样,您的团队可以使用任何Selenium工具实现自动化。使用Docker,您可以运行自己的WebDriverManager服务器,然后您要做的就是编写非常简单的代码以从中下载驱动程序:
# Mac OSX command
docker run -p 4041:4041 -v $HOME/wdm:/root/.m2/repository bonigarcia/webdrivermanager:4.0.0
# Windows command
docker run -p 4041:4041 -v %USERPROFILE%/wdm:/root/.m2/repository bonigarcia/webdrivermanager:4.0.0
驱动程序将存储在本地$ HOME / wdm文件夹中,以及docker镜像中。在Docker中,将其设置为通过自动重启策略保持守护进程状态。在AWS或Azure上托管此服务非常便宜,因为它只需要最少的硬件即可运行它。
这是查询服务的样子(使用Insomnia rest客户端):
> GET /firefoxdriver?os=LINUX HTTP/1.1
> Host: localhost:4041
> User-Agent: insomnia/7.1.1
> Accept: */*
< HTTP/1.1 200 OK
< Date: Sat, 04 Jul 2020 17:56:07 GMT
< Server: Javalin
< Content-Type: text/plain
< Content-Disposition: attachment; filename="geckodriver"
< Transfer-Encoding: chunked
* Received 15.8 KB chunk
* Received 15.6 KB chunk
....
注意:我真的很喜欢这个解决方案,但是当涉及到它时,我可能更喜欢使用Aerokube dockerized浏览器容器实现自动化,例如使用“ Moon framework”,它的价格仅为$ 5 /线程/月运行dockerized浏览器测试的Selenium网格。
#5 楼
首先,@ Asyranok是正确的,即使已实现的自动更新代码在100%的时间内都无法正常工作。但是,对于我们许多人来说,偶尔的停机时间只要几天就可以了。我发现,每隔几个月手动更新X个服务器会令人难以置信,而且写得很好在有关如何“自动更新”驱动程序的硒网站上,我尚未看到该指南的一个公开可用的非库实现。
我的回答特定于C#,对于这种语言,通常建议的解决方案是使用NuGet自动拉动最新的驱动程序,这有两个问题:
您需要以chrome更新的频率进行部署(大多数公司都还没有,我们也不是)或在chrome更新和部署应用程序的“新”版本之间,您的应用程序将被“破坏”,同样,这仅在按计划发布,临时发布的情况下才需要进行。一系列手动步骤进行更新,构建,发布等,以使您的应用程序再次运行。
您需要(通常没有任何解决方法)从NuGet手动拉出最新的chromedrive,再次手动进行操作。
python和@leminhnguyenHUST应该是什么建议使用哪个库,该库会在运行时自动提取最新的chromedriver。我环顾四周,还没有找到任何可用于C#的东西,所以我决定将自己的东西放进我的应用程序中:
public void DownloadLatestVersionOfChromeDriver()
{
string path = DownloadLatestVersionOfChromeDriverGetVersionPath();
var version = DownloadLatestVersionOfChromeDriverGetChromeVersion(path);
var urlToDownload = DownloadLatestVersionOfChromeDriverGetURLToDownload(version);
DownloadLatestVersionOfChromeDriverKillAllChromeDriverProcesses();
DownloadLatestVersionOfChromeDriverDownloadNewVersionOfChrome(urlToDownload);
}
public string DownloadLatestVersionOfChromeDriverGetVersionPath()
{
//Path originates from here: https://chromedriver.chromium.org/downloads/version-selection
using (RegistryKey key = Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\chrome.exe"))
{
if (key != null)
{
Object o = key.GetValue("");
if (!String.IsNullOrEmpty(o.ToString()))
{
return o.ToString();
}
else
{
throw new ArgumentException("Unable to get version because chrome registry value was null");
}
}
else
{
throw new ArgumentException("Unable to get version because chrome registry path was null");
}
}
}
public string DownloadLatestVersionOfChromeDriverGetChromeVersion(string productVersionPath)
{
if (String.IsNullOrEmpty(productVersionPath))
{
throw new ArgumentException("Unable to get version because path is empty");
}
if (!File.Exists(productVersionPath))
{
throw new FileNotFoundException("Unable to get version because path specifies a file that does not exists");
}
var versionInfo = FileVersionInfo.GetVersionInfo(productVersionPath);
if (versionInfo != null && !String.IsNullOrEmpty(versionInfo.FileVersion))
{
return versionInfo.FileVersion;
}
else
{
throw new ArgumentException("Unable to get version from path because the version is either null or empty: " + productVersionPath);
}
}
public string DownloadLatestVersionOfChromeDriverGetURLToDownload(string version)
{
if (String.IsNullOrEmpty(version))
{
throw new ArgumentException("Unable to get url because version is empty");
}
//URL's originates from here: https://chromedriver.chromium.org/downloads/version-selection
string html = string.Empty;
string urlToPathLocation = @"https://chromedriver.storage.googleapis.com/LATEST_RELEASE_" + String.Join(".", version.Split('.').Take(3));
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlToPathLocation);
request.AutomaticDecompression = DecompressionMethods.GZip;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
html = reader.ReadToEnd();
}
if (String.IsNullOrEmpty(html))
{
throw new WebException("Unable to get version path from website");
}
return "https://chromedriver.storage.googleapis.com/" + html + "/chromedriver_win32.zip";
}
public void DownloadLatestVersionOfChromeDriverKillAllChromeDriverProcesses()
{
//It's important to kill all processes before attempting to replace the chrome driver, because if you do not you may still have file locks left over
var processes = Process.GetProcessesByName("chromedriver");
foreach (var process in processes)
{
try
{
process.Kill();
}
catch
{
//We do our best here but if another user account is running the chrome driver we may not be able to kill it unless we run from a elevated user account + various other reasons we don't care about
}
}
}
public void DownloadLatestVersionOfChromeDriverDownloadNewVersionOfChrome(string urlToDownload)
{
if (String.IsNullOrEmpty(urlToDownload))
{
throw new ArgumentException("Unable to get url because urlToDownload is empty");
}
//Downloaded files always come as a zip, we need to do a bit of switching around to get everything in the right place
using (var client = new WebClient())
{
if (File.Exists(System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + "\chromedriver.zip"))
{
File.Delete(System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + "\chromedriver.zip");
}
client.DownloadFile(urlToDownload, "chromedriver.zip");
if (File.Exists(System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + "\chromedriver.zip") && File.Exists(System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + "\chromedriver.exe"))
{
File.Delete(System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + "\chromedriver.exe");
}
if (File.Exists(System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + "\chromedriver.zip"))
{
System.IO.Compression.ZipFile.ExtractToDirectory(System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + "\chromedriver.zip", System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location));
}
}
}
然后通常我会坚持使用这个非常hacky在我的应用程序开始时调用来调用此功能,并确保最新的chromedriver可用于我的应用程序:
//This is a very poor way of determining if I "need" to update the chromedriver,
//however I've yet to figure out a better way of doing this...
try
{
using (var chromeDriver = SetupChromeDriver())
{
chromeDriver.Navigate().GoToUrl("www.google.com");
chromeDriver.Quit();
}
}
catch
{
DownloadLatestVersionOfChromeDriver();
}
我敢肯定,这可以得到很大的改善,但是到目前为止,它对我来说是有效的。
注意:十字张贴在这里
#6 楼
使用软件包的最佳方法chromedriver-autoinstaller
对我来说很完美。我会定期使用一些自动化脚本来创建报告。
请查看文档以了解更多详细信息。
https://pypi.org/project/chromedriver-autoinstaller/
评论
您使用哪种依赖性管理工具?当前未使用任何依赖工具。我正在用Python编写脚本。你能提到任何可以使用的工具吗?