繁体   English   中英

使用.NET核心库csproj中的Selenium WebDriver

[英]Using Selenium WebDriver in library csproj with .NET Core

我正在尝试使用Selenium和.NET Core组建一个网络抓取应用程序,但是我无法找到我的WebDriver exe

我有一个.csproj,它将运行项目的API,调用(以及其他)另一个将处理webscraping的.csproj。 所有都在单个.sln中,并且都运行.NET Core 2.1

在抓取项目中,我已经安装了Selenium.WebDriverSelenium.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>

似乎相当清楚(虽然它令人失望地没有告诉你“当前目录”是什么意思。我将立即提交PR)


通过观察重建期间的变化以及其他在线研究,我看到:

  • nuget包中的所有dllexe都存储在Global Nuget缓存中,而不是解决方案目录中的nuget packages文件夹。
  • chromedriver.exe似乎被复制到<solutionFolder>\\<ScrapingProjectFolder>\\bin\\Debug\\chromeDriver.exe
    • 我认为这就是ChromeDriver Nuget包的功能; 当然我自己没有配置它。
    • 对于ChromeDriver软件包而言,这表面看起来像是一个合理的事情,试图“安装它来制作new ChromeDriver() JustWork”。
  • 深入研究WebDriver代码库,发现它正在查看的“currentDirectory”是“ WebDriver.dll的位置”。
    • 就我而言,那是“ <globalNugetPackagesCache>\\selenium.webdriver\\3.141.0\\lib\\netstandard2.0
    • 似乎我不应该试图让chromedriver.exe最终进入这个文件夹 - 将它复制到另一个包的全局缓存似乎是错误的? (人们同意吗?)
  • 这篇文章似乎得出了大致相同的结论,并说解决方案是调用驱动程序:

    new ChromeDriver(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location))

    • 不幸的是,该路径将我带到<solutionFolder>\\<APIProjectFolder>\\bin\\Debug\\<ScrapingProjectFolder>.dll ,因为dll会被复制到API项目的文件夹中。

我想到了几个解决方案,其中没有一个真正吸引人:

  • 我可以将Selenium.WebDriver.ChromeDriver安装到API项目中。
    • Eww ... API项目不了解WebDriver或Selenium,现在Scraping项目没有驱动程序exe。
  • 我可以手动明确地将exe复制到正确的位置。
    • 感觉不对,感觉很脆弱。 我怀疑这会让部署变得痛苦。
  • 我可以手动将ChromeDriver构造函数指向硬编码路径,我恰好知道它包含当前的exe
    • 似乎与上面类似; 虽然不是那么糟糕。
  • ??? 有没有办法让项目的所有DLL等编译成一个公共文件夹? ???

是否有一种好的,非黑客的方法来解决这个问题。 这将导致JustWorks的git repo,并且将来部署到服务器将会相对轻松?

我上面描述的任何事情是错误的,还是错误配置的?

根据我的理解,你有一个依赖于Scraping项目的API项目。

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.csprojdotnet publish API.csproj API.csproj ChromeDriver软件包在NuGet包中具有自定义构建目标,因此它是自定义的

你现在可以使用了

new ChromeDriver(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));

dotnet run API.csproj

如果我错了,请纠正我。 您有某种类库已引用Selenium,并且您希望使用ChromeDriver.exe但是您收到的错误是在以下位置找不到的。 这很简单。 目前您正在引用类库,可以说Foo到API。 您的装配位置将指向API bin位置,而chromedriver.exe位于类库bin下。 如果是这种情况,您唯一需要做的就是将chromedriver.exe复制到最终的bin目录,即API。

将以下Post Build Event添加到您的API项目中以复制chromedriver:

  <Target Name="PostBuild" AfterTargets="PostBuildEvent">
    <Exec Command="copy $(SolutionDir)\ClassLibrary\bin\Debug\netstandard2.0\chromedriver.exe $(TargetDir)" />
  </Target>

这会将您的chromedriver.exe复制到API bin。 稍后在初始化ChromeDriver时使用:

        var options = new ChromeOptions();
        var service = ChromeDriverService.CreateDefaultService(AppDomain.CurrentDomain.BaseDirectory);

        WebDriver = new ChromeDriver(service, options);

AppDomain.CurrentDomain.BaseDirectory将指向您的API bin目录。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM