Python+selenium+Chrome headless

前言:
使用selenium执行网络爬虫程序时,考虑执行效率和某些其他原因,不希望爬虫工作时显式显示页面。

通过网上查询资料,该需求可以使用PhantomJS浏览器实现,也可以使用Chrome 浏览器的headless Browser模式实现。由于现在好像selenium不在支持PhantomJS了,所以主要采用Chrome Headless模式实现。

  1. 什么是Headless模式
    Headless Browser模式是浏览器的无界面状态,即在不打开浏览器界面的情况下使用浏览器。 该模式的好处如下:
    1)可以加快web自动化测试的执行时间,对于web自动化测试,少了真实浏览器加载css,js以及渲染页面的工作。无界面测试要比真实浏览器快的多。
    2)可以在无界面的服务器或CI上运行测试,减少了外界的干扰,使自动化测试更稳定。
    3)可以更便捷的运行web自动化,编写爬虫、截图等。通常是由编程或者命令行来控制的。
  2. 基础环境
    python:3.x
    python的selenium库: 3.141.0
    chrome浏览器: 91.0.4472.114
    注意:一定要确保chrome浏览器和chromedriver版本对应
  3. selenium使用Chrome headless模式
    如何通过selenium调用Chrome headless模式呢? 下面是python的代码
from selenium import webdriver
#创建Chrome浏览器设置变量
chrome_options = webdriver.ChromeOptions()
#无界面模式
chrome_options.add_argument('--headless')
#实例化Chrome driver
driver=webdriver.Chrome(chrome_options=chrome_options)
#打开百度
driver.get("https://www.baidu.com/")
  1. 设置浏览器窗口大小
chrome_options.add_argument('--window-size=1920,1080')
  1. 打开新的标签页
    js代码可window.open(url)可在新窗口打开一个网页, dirver可执行js代码,具体代码如下:
js="window.open('http://www.baidu.com/')"
driver.execute_script(js)
  1. 切换窗口
    比如我们打开的第一个页面是[百度地图], 第2个窗口打开的页面是百度.如果我们想在第2个页面的输入框输入selenium,代码如下
from selenium import webdriver
#创建Chrome浏览器设置变量
chrome_options = webdriver.ChromeOptions()
#无界面模式
chrome_options.add_argument('--headless')
#设置窗口大小
chrome_options.add_argument('--window-size=1920,1080')
#实例化Chrome driver
driver=webdriver.Chrome(chrome_options=chrome_options)
#打开百度地图页面
driver.get("https://map.baidu.com/")

js="window.open('http://www.baidu.com')"
driver.execute_script(js)
driver.find_element_by_id("kw").send_keys("selenium")
driver.save_screenshot("baidu-map5.png")
driver.quit()

但是很奇怪, 代码报错了,no such element: Unable to locate element: {“method”:“id”,“selector”:“kw”} 找不到这个元素.但是我们看百度的页面命名可以找到这个元素啊. 我们在这步操作之前截一张图就可以看出来,页面扔在第一个页面,即百度地图的页面, 这时候我们需要切换一些窗口.

注意: 以前的方法,diver.switch_to_window() 已经被driver.switch_to.window替代

search_windows=driver.current_window_handle
all_handles=driver.window_handles
for handle in all_handles:
    if handle !=search_windows:
        driver.switch_to.window(handle)
  1. 关闭窗口和关闭浏览器
#关闭浏览器
driver.quit()
#关闭标签页
driver.close()

这2个的使用场景是不同的:

  1. 在我们的case执行完对浏览器的操作后,一定要加上driver.quit() ,不然会导致内存爆满;
  2. 如果我们只想关闭一个窗口, 则用driver.close()
  1. 添加代理
chrome_options.add_argument("--proxy-server=http://" + ip:port)
  1. 修改User-Agent
# 修改User-Agent
chrome_options.add_argument('user-agent= '你想修改成的User-Agent')
  1. 禁用图片
chrome_options.add_argument('blink-settings=imagesEnabled=false')