在带有 .NET Core 的库 csproj 中使用 Selenium WebDriver
Using Selenium WebDriver in library csproj with .NET Core
我正在尝试使用 Selenium 和 .NET Core 构建一个网络抓取应用程序,但我无法找到我的 WebDriver exe
s。
我有一个 .csproj 将 运行 项目的 API,它调用(除其他外)另一个将处理网络抓取的 .csproj。
所有都在一个 .sln 中,并且都是 运行ning .NET Core 2.1
在抓取项目中,我安装了 nuget Selenium.WebDriver
和 Selenium.WebDriver.ChromeDriver
。
我在 API 中创建了一个端点,它调用了抓取项目,运行 是一个尝试调用 new ChromeDriver()
的方法。它不起作用 :( 具体来说,我得到:
The chromedriver.exe file does not exist in the current directory or in a directory on the PATH environment variable. The driver can be downloaded at ... <url>
看起来相当清楚(虽然令人失望的是它没有告诉你 "current directory" 是什么意思。我会立即提交 PR)
通过观察重建期间的变化以及其他在线研究,我发现:
- nuget 包中的所有
dll
和 exe
都存储在全局 Nuget 缓存中,而不是解决方案目录中的 nuget packages
文件夹中。
- 这似乎是预期的行为:"Bug" raised in dotnet Std; MSDN migration docs。
chromedriver.exe
似乎被复制到 <solutionFolder>\<ScrapingProjectFolder>\bin\Debug\chromeDriver.exe
。
- 我假设这就是
ChromeDriver
Nuget 包的作用;当然是我自己没有配置。
- 从表面上看,ChromeDriver 包尝试这样做是合理的 "install this to make
new ChromeDriver()
JustWork."
- 深入研究 WebDriver 代码库,发现它正在查看的 "currentDirectory" 是 "the location of
WebDriver.dll
"。
- 在我的例子中,这是“
<globalNugetPackagesCache>\selenium.webdriver.141.0\lib\netstandard2.0
”
- 我似乎不应该尝试让
chromedriver.exe
最终出现在这个文件夹中 - 将它复制到不同包的全局缓存中似乎是错误的? (大家同意吗?)
This article 似乎得出了大致相同的结论,并表示解决方案是将驱动程序调用为:
new ChromeDriver(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location))
- 不幸的是,该路径将我带到
<solutionFolder>\<APIProjectFolder>\bin\Debug\<ScrapingProjectFolder>.dll
,因为 dll 被复制到 API 项目的文件夹中。
我想到了几个解决方案,none 其中非常有吸引力:
- 我可以将
Selenium.WebDriver.ChromeDriver
安装到 API 项目中。
- Eww...API 项目不知道 WebDriver 或 Selenium,现在 Scraping 项目没有驱动程序 exe。
- 我可以手动明确地将 exe 复制到正确的位置。
- 感觉不太对劲,感觉很脆弱。我怀疑这会使部署变得痛苦。
- 我可以手动将 ChromeDriver 构造函数指向硬编码路径,我恰好知道该路径包含当前
exe
。
- 与上面类似;虽然没那么糟糕。
- ???有什么方法可以将一个项目的所有 DLL 等编译到一个公共文件夹中吗? ???
有没有好的、简单的方法来解决这个问题。这将产生一个 JustWorks 的 git 回购,并且将来部署到服务器会相对轻松吗?
我上面描述的任何事情是否有误或配置错误?
据我了解,您有一个 API 项目依赖于一个 Scraping 项目。
Scraping.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>7.2</LangVersion>
<PublishChromeDriver>true</PublishChromeDriver>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Selenium.WebDriver" Version="3.141.0" />
<PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="2.46.0" />
</ItemGroup>
</Project>
API.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\Scraping\Scraping.csproj" />
</ItemGroup>
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>7.2</LangVersion>
</PropertyGroup>
</Project>
诀窍是将 <PublishChromeDriver>true</PublishChromeDriver>
添加到传递项目以使其在 运行 dotnet publish API.csproj
时发布 chromedriver ChromeDriver 包在 NuGet 包中具有自定义构建目标,因此它是 自定义.
您现在可以使用
new ChromeDriver(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
和dotnet run API.csproj
如有错误请指正。您有某种引用了 Selenium 的 Class 库,并且您想使用 ChromeDriver.exe,但您收到一个错误消息,指出无法在以下位置找到它。这相当简单。
当前您正在引用 Class 库让 API 说 Foo。您的组装位置将指向 API 库位置,而 chromedriver.exe 位于 Class 库库下方。
如果是这种情况,您唯一需要做的就是将 chromedriver.exe 之后的内容复制到最终的 bin 目录,即 API.
将以下 Post 构建事件添加到您的 API 项目以复制 chromedriver:
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="copy $(SolutionDir)\ClassLibrary\bin\Debug\netstandard2.0\chromedriver.exe $(TargetDir)" />
</Target>
这会将您的 chromedriver.exe 复制到 API 垃圾箱。稍后在初始化 ChromeDriver 时使用:
var options = new ChromeOptions();
var service = ChromeDriverService.CreateDefaultService(AppDomain.CurrentDomain.BaseDirectory);
WebDriver = new ChromeDriver(service, options);
而 AppDomain.CurrentDomain.BaseDirectory
将指向您的 API bin 目录。
我正在尝试使用 Selenium 和 .NET Core 构建一个网络抓取应用程序,但我无法找到我的 WebDriver exe
s。
我有一个 .csproj 将 运行 项目的 API,它调用(除其他外)另一个将处理网络抓取的 .csproj。 所有都在一个 .sln 中,并且都是 运行ning .NET Core 2.1
在抓取项目中,我安装了 nuget Selenium.WebDriver
和 Selenium.WebDriver.ChromeDriver
。
我在 API 中创建了一个端点,它调用了抓取项目,运行 是一个尝试调用 new ChromeDriver()
的方法。它不起作用 :( 具体来说,我得到:
The chromedriver.exe file does not exist in the current directory or in a directory on the PATH environment variable. The driver can be downloaded at ... <url>
看起来相当清楚(虽然令人失望的是它没有告诉你 "current directory" 是什么意思。我会立即提交 PR)
通过观察重建期间的变化以及其他在线研究,我发现:
- nuget 包中的所有
dll
和exe
都存储在全局 Nuget 缓存中,而不是解决方案目录中的 nugetpackages
文件夹中。- 这似乎是预期的行为:"Bug" raised in dotnet Std; MSDN migration docs。
chromedriver.exe
似乎被复制到<solutionFolder>\<ScrapingProjectFolder>\bin\Debug\chromeDriver.exe
。- 我假设这就是
ChromeDriver
Nuget 包的作用;当然是我自己没有配置。 - 从表面上看,ChromeDriver 包尝试这样做是合理的 "install this to make
new ChromeDriver()
JustWork."
- 我假设这就是
- 深入研究 WebDriver 代码库,发现它正在查看的 "currentDirectory" 是 "the location of
WebDriver.dll
"。- 在我的例子中,这是“
<globalNugetPackagesCache>\selenium.webdriver.141.0\lib\netstandard2.0
” - 我似乎不应该尝试让
chromedriver.exe
最终出现在这个文件夹中 - 将它复制到不同包的全局缓存中似乎是错误的? (大家同意吗?)
- 在我的例子中,这是“
This article 似乎得出了大致相同的结论,并表示解决方案是将驱动程序调用为:
new ChromeDriver(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location))
- 不幸的是,该路径将我带到
<solutionFolder>\<APIProjectFolder>\bin\Debug\<ScrapingProjectFolder>.dll
,因为 dll 被复制到 API 项目的文件夹中。
- 不幸的是,该路径将我带到
我想到了几个解决方案,none 其中非常有吸引力:
- 我可以将
Selenium.WebDriver.ChromeDriver
安装到 API 项目中。- Eww...API 项目不知道 WebDriver 或 Selenium,现在 Scraping 项目没有驱动程序 exe。
- 我可以手动明确地将 exe 复制到正确的位置。
- 感觉不太对劲,感觉很脆弱。我怀疑这会使部署变得痛苦。
- 我可以手动将 ChromeDriver 构造函数指向硬编码路径,我恰好知道该路径包含当前
exe
。- 与上面类似;虽然没那么糟糕。
- ???有什么方法可以将一个项目的所有 DLL 等编译到一个公共文件夹中吗? ???
有没有好的、简单的方法来解决这个问题。这将产生一个 JustWorks 的 git 回购,并且将来部署到服务器会相对轻松吗?
我上面描述的任何事情是否有误或配置错误?
据我了解,您有一个 API 项目依赖于一个 Scraping 项目。
Scraping.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>7.2</LangVersion>
<PublishChromeDriver>true</PublishChromeDriver>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Selenium.WebDriver" Version="3.141.0" />
<PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="2.46.0" />
</ItemGroup>
</Project>
API.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\Scraping\Scraping.csproj" />
</ItemGroup>
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>7.2</LangVersion>
</PropertyGroup>
</Project>
诀窍是将 <PublishChromeDriver>true</PublishChromeDriver>
添加到传递项目以使其在 运行 dotnet publish API.csproj
时发布 chromedriver ChromeDriver 包在 NuGet 包中具有自定义构建目标,因此它是 自定义.
您现在可以使用
new ChromeDriver(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
和dotnet run API.csproj
如有错误请指正。您有某种引用了 Selenium 的 Class 库,并且您想使用 ChromeDriver.exe,但您收到一个错误消息,指出无法在以下位置找到它。这相当简单。 当前您正在引用 Class 库让 API 说 Foo。您的组装位置将指向 API 库位置,而 chromedriver.exe 位于 Class 库库下方。 如果是这种情况,您唯一需要做的就是将 chromedriver.exe 之后的内容复制到最终的 bin 目录,即 API.
将以下 Post 构建事件添加到您的 API 项目以复制 chromedriver:
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="copy $(SolutionDir)\ClassLibrary\bin\Debug\netstandard2.0\chromedriver.exe $(TargetDir)" />
</Target>
这会将您的 chromedriver.exe 复制到 API 垃圾箱。稍后在初始化 ChromeDriver 时使用:
var options = new ChromeOptions();
var service = ChromeDriverService.CreateDefaultService(AppDomain.CurrentDomain.BaseDirectory);
WebDriver = new ChromeDriver(service, options);
而 AppDomain.CurrentDomain.BaseDirectory
将指向您的 API bin 目录。