Python Selenium - 在无图形Linux机器上使用selenium的几种方案

研究爬虫的时候,用到了chrome headless,于是想到PhantomJS停止维护了,headless Chrome能否完全替代PhantomJS,是否需要其他的驱动安装呢?做了一些简单的实验并记录一下在无图形Linux机器上使用selenium的几种方案。


为什么我们要无头启动浏览器?

在无图形的Linux机器上使用selenium运行自动化用例,将能够节约资源和执行时间。

1) 可以将大量自动化用例串行发布到多台精简的Linux机器(Lean,VM)上执行

2) 隐式执行web自动化用例的效率比启动浏览器要快,无论是加在页面元素还是执行javascript脚本等。


怎么做?下面列出一些解决方案。

PhantomJS 

- http://phantomjs.org/, 相信也是chrome支持headless之前,大多数人采用的解决方案。

brew install phantomjs
from pyvirtualdisplay import Display
from selenium import webdriver

driver = webdriver.PhantomJS()
driver.set_window_size(1920, 1080)
driver.get("https://www.baidu.com/")
driver.find_element_by_id('kw').send_keys("鲁冰花")
driver.find_element_by_id("su").click()
print driver.current_url
driver.quit()


Xvfb 和 PyVirtualDisplay

使用这个解决方案,将可以兼容多种浏览器的webdriver,chrome,firefox,等等
yum/apt-get install Xvfb
pip install PyVirtualDisplay

检查DISPLAY设置,默认应该是 :1 

env | grep DISPLAY
from pyvirtualdisplay import Display 
display = Display(visible=0, size=(1920, 1080)) 
display.start() 
driver = webdriver.Chrome(driver_path='<path-to-driver>/chromedriver') # driver = webdriver.Firefox() ...
driver.get('https://www.baidu.com') 
print(driver.title) 
driver.quit()
display.stop()

Chrome Headless

最新版的chrome支持headless模式,这导致phamtomJS的维护者中止了该项目的维护。 :( 实验时候发现Chrome Headless除了新版的google-chrome和chromedriver之外,不需要额外安装其他组件或驱动。在headless模式下,可以实现所有操作,完美替代PhantomJS。

更新google-chrome到最新版,下载新版chromedriver

yum update google-chrome
wget https://chromedriver.storage.googleapis.com/2.35/chromedriver_linux64.zip
unzip chromedriver_linux64.zip

from selenium import webdriver
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless') 
chrome_options.add_argument('--no-sandbox')  
driver = webdriver.Chrome(driver_path='<path-to-driver>/chromedriver', chrome_options=chrome_options,
  service_args=['--verbose', '--log-path=<path-to-log>/chromedriver.log'])
...

headless模式下,chromedriver会打印一行错误信息,

[0515/160034.252:ERROR:gpu_process_transport_factory.cc(1007)] Lost UI shared context.

这是因为在headless模式下,浏览器无法调用GPU的接口。

这导致基于类似WebGL实现的应用,没办法在chrome headless模式下完成element捕捉。(也许有解决方案,但是尚未学习到。)


想要了解更多chrome headless的信息:

https://developers.google.com/web/updates/2017/04/headless-chrome 

没有更多推荐了,返回首页