一、运行环境

selenium 支持 Chrome、Firefox、Safari 等主流浏览器。下面以 Chrome 浏览器为例。

1.1 Windows 环境部署

  1. 安装 Python3,用 pip 安装 selenium 包。

  2. 从官网下载安装 Chrome 浏览器。

  3. 下载 Chrome 浏览器驱动 chromedriver(下载地址),放在任意目录下,并加入 PATH 环境变量。

    注意:chromedriver 的版本要与 Chrome 浏览器的版本对应(在浏览器地址栏输入 about:version 可以查看浏览器版本,版本号看前三位就行)

1.2 Linux 环境部署

1.2.1 安装 Python3 和 selenium 包

  1. 下载 Python3 源码(下载地址),编译安装:

    1
    2
    3
    4
    $ wget https://www.python.org/ftp/python/3.7.2/Python-3.7.2.tgz
    $ tar -xzf Python-3.7.2.tgz
    $ cd Python-3.7.2
    $ sudo ./configure && sudo make && sudo make install
  2. 安装 selenium 包

    1
    $ sudo pip3 install selenium

1.2.2 安装 Chrome 浏览器(CentOS 7)

  1. 配置 yum 源

    1
    $ sudo vim /etc/yum.repos.d/google-chrome.repo

    写入以下内容:

    1
    2
    3
    4
    5
    6
    [google-chrome]
    name=google-chrome
    baseurl=http://dl.google.com/linux/chrome/rpm/stable/$basearch
    enabled=1
    gpgcheck=1
    gpgkey=https://dl-ssl.google.com/linux/linux_signing_key.pub
  2. yum 安装 google-chrome 浏览器

    1
    $ sudo yum -y install google-chrome-stable --nogpgcheck  # 由于 Google 官方源被墙,需要加 --nogpgcheck 参数,以防安装失败

1.2.3 安装 Chrome 浏览器(Ubuntu)

  1. 安装 Chrome 浏览器官方 PPA:

    1
    2
    $ sudo wget http://www.linuxidc.com/files/repo/google-chrome.list -P /etc/apt/sources.list.d/
    $ wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
  2. 安装 Chrome 浏览器:

    1
    2
    $ sudo apt update
    $ sudo apt install google-chrome-stable

1.2.4 下载 chromedriver

下载地址注意事项与 Windows 相同。下载完成后移动到 /usr/bin/usr/local/bin 目录下,或者也可以将 chromedriver 所在目录加入 PATH 环境变量。

二、selenium 的基本操作

2.1 开始使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from selenium import webdriver	# 导入 webdriver
import time # selenium 经常会用到 time.sleep(time)。因为 selenium 可能会在网页没有完全加载完成时就去获取和操作 DOM,导致出错,所以适当使用 time.sleep(time) 以防出错

driver = webdriver.Chrome() # 打开 Chrome 浏览器

driver.get(url) # get 方法打开网页

driver.maximize_window() # 最大化窗口(因为有时候需要根据屏幕像素定位,所以最大化是有必要的)
driver.minimize_window() # 最小化窗口

driver.page_source # 网页源代码
driver.save_screenshot('screenshot.png') # 保存当前网页截图

driver.close() # 关闭当前窗口
driver.quit() # 关闭所有窗口并退出浏览器,清除临时目录下的临时文件

2.2 DOM 操作

2.2.1 查找元素

1
2
3
4
el = driver.find_element_by_id(id) # 根据 id 查找元素。同样的方法还有根据 类名、标签名、xpath、css选择器 查找
child_el = parent_el.find_element_by_class_name(class_name) # find_element(s)_by_xxx 方法也可以通过一个元素调用,这样只会在其子元素中查找符合条件的元素

parent_el = child_el.find_element_by_xpath('./..') # selenium 没有原生提供根据子元素获取父元素的方法,只能通过 xpath 的语法来做到这一点

如果要获取兄弟结点,有两种方法:

  1. 先获取父节点,再通过父节点获取兄弟结点;
  2. 使用 xpath 语法中的 preceding-sibling、following-sibling 等(TODO)

2.2.2 处理元素

1
2
3
4
5
6
7
8
9
el.click()	# 点击元素
el.clear() # 如果是输入框,清空框里的东西
el.send_keys(string) # 如果是输入框,将 string 填写到框中
el.submit() # 自动寻找 el 最近的表单并提交
el.save_screenshot("el_screenshot.png") # 保存当前元素的截图

el.text # 元素的文本内容
el.get_attribute(attr_name) # 获取元素某个属性的属性值
el.value_of_css_property(style_name) # 获取元素的某个 css 属性的值

2.3 处理 cookies

1
2
3
4
5
6
cookies = driver.get_cookies()	# 获取 cookies(是一个列表。列表每个元素都是一个 cookie,以字典形式存储)

driver.add_cookie(cookie) # 添加一个 cookie,以后继续通过 selenium 操作浏览器时都会使用这个 cookie

for cookie in cookies: # 迭代添加所有 cookie
driver.add_cookie(cookie)

2.4 处理对话框

1
2
3
4
5
alert = driver.switch_to.alert  # 定位到 alert 对话框
alert.accept() # 相当于点击 alert 对话框中的“确定”按钮
alert.dismiss() # 相当于点击 alert 对话框中的“取消”按钮

alert.text # alert 对话框的文本内容

2.5 多个窗口的处理

1
2
3
driver.window_handles	# 所有窗口的句柄(是一个列表)

driver.switch_to_window(handle) # 聚焦到某个窗口

2.6 处理 iframe

网页中存在 iframe 标签时,要想操作 iframe 包含的网页,必须:

1
driver.switch_to_frame(iframe_id)

使用下面这行代码回到外层网页:

1
driver.switch_to_default_content()

2.7 复杂点击和按键事件

单击事件是最常用的操作,可以直接 el.click() 调用。其他点击和按键事件则需要导入另一个类:

1
2
3
4
5
6
from selenium.webdriver.common.action_chains import ActionChains   # 导入 ActionChains 类

ActionChains(driver).double_click(el).perform()
# ActionChains(driver) ———— 创建对象,参数是 driver;
# double_click(el) ———— 鼠标双击事件,参数是要双击的元素;
# 写了 perform(),该操作才会执行

三、Chrome 无头模式

没有图形界面的主机上,浏览器无法启动,此时可以用 Chrome 的无头模式运行selenium。(无头模式只是没有打开 GUI,但浏览器的渲染工作是真真正正在进行的)

使用无头模式:

1
2
3
4
5
from selenium import webdriver

chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless') # 运行 Chrome 时附加参数 --headless,表示以无头模式运行
driver = webdriver.Chrome(chrome_options=chrome_options)

无头模式基本操作与一般模式相同。

无头模式中经常会用到保存截图的操作:driver.save_screenshot(path)el.save_screenshot(path),可以通过查看截图了解运行过程。

四、启动带有用户配置的浏览器

1
2
3
4
5
from selenium import webdriver

chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--user-data-dir=' + r'用户配置所在目录')
driver = webdriver.Chrome(chrome_options=chrome_options)

在浏览器中输入 chrome://version,找到 个人资料路径,删除最后的 /default,剩下的就是用户配置所在目录。

五、遇到过的问题及解决方法

  1. linux 上以 root 身份运行 Chrome 时需要加 --no-sandbox 参数:

    1
    2
    3
    chrome_options = webdriver.ChromeOptions()
    chrome_options.add_argument('--no-sandbox')
    driver = webdriver.Chrome(chrome_options=chrome_options)
  2. linux 上运行脚本时,需要在脚本开头加

    1
    2
    #!/usr/local/bin/python3
    # -*-coding:utf8-*-
  3. CentOS 下,如果要将脚本加入计划任务中定时运行,Python3 和脚本位置都必须是绝对路径

  4. 曾遇到过这种情况:linux 下手动执行脚本,执行成功;但用任务计划程序定时自动执行时,显示 chromedriver 不在环境变量中。这是因为使用任务计划程序时,环境变量 PATH 只包含 /usr/bin:/bin,只是正常情况下的一部分,所以最好将 chromedriver 放在 /usr/bin/bin 路径下。