zoukankan      html  css  js  c++  java
  • Docker环境下运行python+selenium+chrome

    Docker环境下运行python+selenium+chrome

    docker运行时占用的资源非常少,而且能将环境进行有效的隔离,可以快速的进行部署,因此可以将docker与selenium结合实现在容器中执行无界面的自动化操作。例如:自动测试、自动下载邮件等。

    需求说明

    通过Selenium自动的登录邮箱,下载邮箱中符合条件的邮件,并对邮件的内容进行解析存档。

    方案选择

    Selenium官方提供了基于selenium hub的方式来管理selenium的node节点,提供了分布式的远程调度方案,可以为SeleniumGrid添加各种类型的WebDriver。

    Selenium Grid架构图

    基于Selenium Grid的方案适用于以下场景:

    1.通过Selenium自动访问网页时,需要阻塞等待与用户的交互,例如需要输入短信验证码的场景,通过Selenium Grid的调度,可以最优的利用所有可访问的资源,提高系统的并发执行效率。

    2.需要对网页的兼容性进行测试时,可以接入多种内核的WebDriver到Selenium Grid中,这样在进行网页的自动化测试时,也同时对浏览器的兼容性进行了测试。

    3.访问只支持IE内核的网站时,例如一些开发比较早的政府网站等。

    4.访问需要安装安全控件的网站,例如网银的登录等。

    本次的需求对时效性要求不高,邮件的获取需要由定时器进行触发,如果使用Selenium Grid,可能会增加了整个系统的复杂程度,分布式系统中每引入一个中间件,就会增加系统的复杂性,系统的可用性就会随之降低。

    基于以上分析,考虑采用selenium handless的模式,在Docker中运行Chrome的WebDriver,完成最终邮件的自动获取。

    在确定方案之后,需要寻找合适的docker镜像,最终找到了chromium-xvfb这个镜像文件,集成了chromium和xvfb,可以满足在Docker容器中通过selenium来进行无界面的操作。

    方案验证

    1.下载chromium-xvfb的镜像文件

    [root@prod ~]# docker pull markadams/chromium-xvfb-py2
    

    2.交互模式运行

    [root@prod ~]# docker run --rm -it markadams/chromium-xvfb-py2 bash
    

    3.进入pytho环境

    root@8016c66877aa:/usr/src/app# python
    

    4.输入以下python代码

    from selenium import webdriver
    driver = webdriver.Chrome()
    url = 'https://github.com/mark-adams/docker-chromium-xvfb/blob/master/samples/python3/test_google.py'
    driver.get(url)
    
    没有错误输出,证明Chrome已经在Docker下可以正常工作。
    

    方案实施

    以markadams/chromium-xvfb-py2作为基础镜像,重新编写的Dockerfile如下:

    FROM markadams/chromium-xvfb-py2
    WORKDIR /opt/zs5s/download-mail
    COPY ./download-mail/.pip /root/.pip/
    COPY ./download-mail/requirements.txt /opt/zs5s/download-mail/requirements.txt
    
    RUN pip install --upgrade pip
    
    RUN pip install -r requirements.txt && mkdir /tmp/downloaded_files
    
    ENV DISPLAY :1
    COPY ./download-mail /opt/zs5s/download-mail
    COPY ./data_service /opt/zs5s/data_service
    COPY ./save_mail /opt/zs5s/save_mail
    COPY ./common/ /opt/zs5s/common
    USER root
    

    在编译运行后,发现在这个docker容器内单纯的去访问网页没有问题,如果去执行带有键盘的操作时,会报错,错误信息如下:

    raise exception_class(message, screen, stacktrace)
    selenium.common.exceptions.WebDriverException: Message: unknown error: an X display is required for keycode conversions, consider using Xvfb
      (Session info: chrome=57.0.2987.98)
      (Driver info: chromedriver=2.28.455506 (18f6627e265f442aeec9b6661a49fe819aeeea1f),platform=Linux 4.4.27-moby x86_64)
    

    经过调查是需要在启动容器时执行Xvfb,申请一块Screen,具体可以参考链接1。在Dockerfile中加入启动脚本:

    CMD sh start.sh
    

    start.sh的内容如下:

    #!/bin/sh
    export DISPLAY=:1   
    Xvfb $DISPLAY -ac -screen 0 1280x1024x8 &
    sleep 1 
    ps -aux 
    tail -f start.sh #测试用,为了阻塞住容器内的进程
    

    结果验证

    在新生成的容器内执行以下的python脚本,可以正常执行,说明在Chrome中已经可以接收通过selenium传入的键盘事件。

    from splinter import Browser
    from selenium import webdriver
    from selenium.webdriver.common.keys import Keys
    url = 'https://github.com/mark-adams/docker-chromium-xvfb/blob/master/samples/python3/test_google.py'
    browser = Browser('chrome')
    browser.visit(url)
    element = browser.find_by_xpath('/html/body/div[1]/header/div/div/div/div/form/label/input[1]')
    element.type('aaaa')
    

    残留问题

    在python退出selenium时,虽然执行了driver.quit()函数,但是实际上Chrome并没有真正的退出,似乎是selenium的一个Bug,在3.1中提到了修正,但是好像没有起作用,
    selenium-commit-url

    解决办法可以考虑执行shell脚本主动的kill掉Chrome的进程。

    参考链接

    1.protractor-sendkeys-not-working-an-x-display-is-required-for-keycode-conversion
    2.crawling-python-selenium-docker
    3.docker-chromium-xvfb

  • 相关阅读:
    常用正则表达式
    在过滤器中设置一个应用范围内的路径
    在过滤器中设置一个应用范围内的路径
    shell編程之遠程開啓多個機器的ElasticSearch
    shell之CMD的使用,是用` `還是" "?
    shell編程之自動化集群搭建並啓動
    shell編程之權限
    登录用户出现‘’-bash-4.2$‘’的问题解决
    locate: can not open `/var/lib/mlocate/mlocate.db': No such file or directory
    Spring之mvc應用(包含aop)
  • 原文地址:https://www.cnblogs.com/xiao-xue-di/p/11474669.html
Copyright © 2011-2022 走看看