selenium是一款老牌的自动化测试工具,也被不少人用做爬虫工具。 通常我们使用时都是在Windows或者带图形界面的Linux系统下,且需配合ChromeDriver(或其他浏览器Driver),但生产环境很多时候是纯命令行的Linux环境;其实在这种条件下,selenium也是可以部署使用的,官方提供了供远程调用的docker实例。
安装环境
安装docker环境,此步不再叙述
之后分别pull selenium Grid(可以认为是selenium的一个分布式组件)和Chrome实例(类比分布式系统中的worker节点)
# 或者直接run,docker会自动拉取本地没有的镜像 docker run -d -p 4444:4444 --name selenium-hub selenium/hub docker run -d -P --link selenium-hub:hub -v /dev/shm:/dev/shm selenium/node-chrome
注意:官方说明中还指定了一种先 docker network create grid创建一个专用网络的方法,此法中除了hub要用--net指定网络外,node-chrome不可以再用--link,即便配合--net也不行,而是要把--link换成设置环境变量
docker run -d --net grid -e HUB_HOST=selenium-hub -v /dev/shm:/dev/shm selenium/node-chrome
这点其实可以理解,docker network本来就是设计用来替代--link的。
上述命令其实就是建立了一个selenium的分布式集群,有一个调度节点和一个工作节点,工作节点可以继续用相同命令添加,我们之后交互的只是调度节点。
假设上述容器都运行在本地(即IP为127.0.0.1),则我们的代码里,做如下修改即可
driver = webdriver.Chrome(executable_path=chromedriver_path) # 上面是本地运行selenium实例,chromedriver_path是chromedriver.exe程序的路径。现在改为如下: driver = webdriver.Remote("http://127.0.0.1:4444/wd/hub")
可以看到,对原工程代码修改的地方只有一行,改动很少,之后我们的采集/测试程序就可以在纯字符界面里工作了。
注意事项
虽然修改后的大部分使用方式没有任何区别,但还有几点需要注意:
- chrom_options = webdriver.ChromeOptions() 可以为启动的浏览器实例指定一些参数,两种模式下写法有些区别
# 本地运行模式 chrom_options = webdriver.ChromeOptions() prefs = { "profile.managed_default_content_settings.images": 2, "profile.managed_default_content_settings.notifications": 2, } chrom_options.add_experimental_option('prefs',prefs) chrom_options.add_argument('--proxy-server=http://' + "192.168.1.111:8888") chrom_options.add_argument("--disable-gpu") driver = webdriver.Chrome(executable_path=chromedriver_path, chrome_options=chrom_options) # 远程运行模式 chrom_options = webdriver.ChromeOptions() prefs = { "profile.managed_default_content_settings.images": 2, "profile.managed_default_content_settings.notifications": 2, } chrom_options.add_experimental_option('prefs',prefs) chrom_options.add_argument('--proxy-server=http://' + "192.168.1.111:8888") chrom_options.add_argument("--disable-gpu") desired_capabilities = chrom_options.to_capabilities() driver = webdriver.Remote("http://127.0.0.1:4444/wd/hub", desired_capabilities=desired_capabilities)
- chrom_options.add_argument(r'--user-data-dir=Z:\UserData\test1')可以让浏览器加载完整的用户配置文件,但此参数在Remote模式下无法使用,同理加载扩展程序的chrome_options.add_extension('D:\crx\AdBlock_v2.17.crx')也无效。
- 需要加上--disable-gpu参数,chrom_options.add_argument("--disable-gpu"),否则会报错。
- driver.quit()同样会关闭远程的浏览器实例,但如果在driver活跃时,用driver.session_id获得当前session_id,且使用完后不quit,下次使用此id还可以继续复用上次未关闭的浏览器,相当于远程浏览器实例和打开的窗口都未关闭。
desired_capabilities = chrom_options.to_capabilities() driver = webdriver.Remote("http://127.0.0.1:4444/wd/hub", desired_capabilities=desired_capabilities) driver.quit() # webdriver.Remote会打开一个新浏览器,我们要复用旧会话,所以退出这个新的 driver.session_id = sessionid # 现在driver已经是上次程序结束时的driver了