.Net6在Docker环境下操作Selenium.Chrome的那些坑

622 篇文章 16 订阅
104 篇文章 7 订阅

目录

实现

Docker中运行的那些坑

1.第一个坑

2.第二个坑

安装chrome相关资料

3.第三个坑

4.第四个坑

5.第五个坑


.Net6中想实现对某个网址截屏,可通过Selenium模拟访问网址并实现截图。

实现

安装Nuget包


<PackageReference Include="Selenium.Chrome.WebDriver" Version="85.0.0" />
<PackageReference Include="Selenium.Support" Version="4.1.0" />
<PackageReference Include="Selenium.WebDriver" Version="4.1.0" />

之后可通过代码实现模拟访问网址并截图​​​​​​​


public static string PageScreenshot(string url, string uploadbasepath)
{
    ChromeDriver driver = null;
    try
    {
        ChromeOptions options = new ChromeOptions();

        options.AddArguments("headless", "disable-gpu", "no-sandbox");
        driver = new ChromeDriver(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), options);

        //driver = new ChromeDriver("/usr/bin/google-chrome-stable", options);
        driver.Navigate().GoToUrl(url);
        string width = driver.ExecuteScript("return document.body.scrollWidth").ToString();
        string height = driver.ExecuteScript("return document.body.scrollHeight").ToString();
        driver.Manage().Window.Size = new System.Drawing.Size(int.Parse(width), int.Parse(height)); //=int.Parse( height);
        var screenshot = (driver as ITakesScreenshot).GetScreenshot();

        //directory create
        var basepath = uploadbasepath + DateTime.Now.ToString("yyyyMMdd") + "/";
        if (!Directory.Exists(uploadbasepath))
        {
            Directory.CreateDirectory(uploadbasepath);
        }
        if (!Directory.Exists(basepath))
        {
            Directory.CreateDirectory(basepath);
        }

        var path = basepath + Guid.NewGuid().ToString("N") + ".jpg";

        screenshot.SaveAsFile(path);
        return path;
    }
    catch (Exception ex)
    {
        throw;
    }
    finally
    {
        if (driver != null)
        {
            driver.Close();
            driver.Quit();
        }
    }
}

需要另外做的一步是把chromedriver从bin/Release/netcoreapp3.1/chromedriver复制到publish目录。

你以为到这就完了?这个代码确实可以在windows/linux非容器环境下运行。但是在docker里还是有些不一样。

Docker中运行的那些坑

首先需要注意.netcore3.1在Docker中操作图片记得安装libgdiplus.so​​​​​​​


#Dockerfile
RUN apt-get update -y && apt-get install -y --allow-unauthenticated libgdiplus && apt-get clean && ln -s /usr/lib/libgdiplus.so /usr/lib/gdiplus.dll

1.第一个坑

首先遇到的就是OpenQA.Selenium.DriverServiceNotFoundException异常,异常信息是

OpenQA.Selenium.DriverServiceNotFoundException: The file /opt/google/chrome/chrome/chromedriver does not exist. The driver can be downloaded at http://chromedriver.storage.googleapis.com/index.html

这个异常明显是找不到chromedriver,那就与在非Docker环境linux中直接运行的方式一样,尝试把chromedriver复制到Docker的publish目录中,在Dockerfile中添加以下内容​​​​​​​

#dockerfile

RUN cp /src/xxx/Release/netcoreapp3.1/chromedriver /app/publish/

2.第二个坑

尝试运行以上容器,还是失败,进入容器内部,直接运行chromedriver,可以看到缺少libxx.so之类的库。那咋办,只能尝试在镜像中安装chrome,这样相关库就有了

安装chrome相关资料

https://stackoverflow.com/questions/55206172/how-to-run-dotnet-core-app-with-selenium-in-docker

https://github.com/devpabloassis/seleniumdotnetcore/blob/master/Dockerfile

那在Dockerfile中添加安装chrome的命令

#Dockerfile Install Chrome
RUN apt-get update && apt-get install -y \
 apt-transport-https \
 ca-certificates \
 curl \
 gnupg \
 hicolor-icon-theme \
 libcanberra-gtk* \
 libgl1-mesa-dri \
 libgl1-mesa-glx \
 libpango1.0-0 \
 libpulse0 \
 libv4l-0 \
 fonts-symbola \
 --no-install-recommends \
 && curl -sSL https://dl.google.com/linux/linux_signing_key.pub | apt-key add - \
 && echo "deb [arch=amd64] https://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google.list \
 && apt-get update && apt-get install -y \
 google-chrome-stable \
 --no-install-recommends \
 && apt-get purge --auto-remove -y curl \
 && rm -rf /var/lib/apt/lists/*

3.第三个坑

运行以上修改后的容器,又一个异常

DevToolsActivePort file doesn't exist

继续查资料发现需要加个参数disable-dev-shm-usage

https://stackoverflow.com/questions/50642308/webdriverexception-unknown-error-devtoolsactiveport-file-doesnt-exist-while-t

但是前面试了不在docker内运行,需要这个参数,那就加个环境变量区分开docker与非docker环境​​​​​​​


#Dockerfile

ENV INDOCKER 1
public static string PageScreenshot(string url, string uploadbasepath)
{
    ChromeDriver driver = null;
    try
    {
        var indocker = Environment.GetEnvironmentVariable("INDOCKER");
        ChromeOptions options = new ChromeOptions();

        if (indocker == "1") 
        {
            options.AddArguments("headless", "disable-gpu", "no-sandbox", "disable-dev-shm-usage");
            //driver = new ChromeDriver("/opt/google/chrome/chrome", options);
        }
        else
        {
            options.AddArguments("headless", "disable-gpu", "no-sandbox");
        }
        driver = new ChromeDriver(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), options);

        //driver = new ChromeDriver("/usr/bin/google-chrome-stable", options);
        driver.Navigate().GoToUrl(url);
        string width = driver.ExecuteScript("return document.body.scrollWidth").ToString();
        string height = driver.ExecuteScript("return document.body.scrollHeight").ToString();
        driver.Manage().Window.Size = new System.Drawing.Size(int.Parse(width), int.Parse(height)); //=int.Parse( height);
        var screenshot = (driver as ITakesScreenshot).GetScreenshot();

        //directory create
        var basepath = uploadbasepath + DateTime.Now.ToString("yyyyMMdd") + "/";
        if (!Directory.Exists(uploadbasepath))
        {
            Directory.CreateDirectory(uploadbasepath);
        }
        if (!Directory.Exists(basepath))
        {
            Directory.CreateDirectory(basepath);
        }

        var path = basepath + Guid.NewGuid().ToString("N") + ".jpg";

        screenshot.SaveAsFile(path);
        return path;
    }
    catch (Exception ex)
    {
        throw;
    }
    finally
    {
        if (driver != null)
        {
            driver.Close();
            driver.Quit();
        }
    }
}

4.第四个坑

尝试运行上面修改后的容器,又一个异常​​​​​​​

This version of ChromeDriver only supports Chrome version 99
Current browser version is 109.0.5414.74 with binary path /usr/bin/google-chrome

这个信息字面意思就是之前第一个坑复制的chromedriver版本较低。那就直接去官网下载最新的chromedriver,并放到镜像内

下载地址:http://chromedriver.storage.googleapis.com/index.html​​​​​​​


# Dockerfile
COPY ["xxx/chromedriver", "."]
RUN chmod +x chromedriver

5.第五个坑

继续尝试运行,发现这次能成功截图了,等等...这字体咋还是乱码呢

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值