selenium 使用教程

Q&A

Q1:如何加载一个页面?

我们可以使用 webdriver.Chrome 方法创建一个浏览器对象,后续所有的关于浏览器的自动化操作都将在该对象上完成。

Q2:如何规避掉 JS 渲染页面不完整的问题?

get 方法在网页框架加载出来之后就结束执行,并没有等待 JS 渲染,Ajax 请求等等。因此需要设置等待时间。等待可以分为隐式等待和显式等待。

显式等待更为推荐,可以通过 WebDriverWait 创建实例,在对应条件未满足时不停止加载。

Q3:获取页面后如何分析页面

selenium 提供了许多分析页面的方法,如 find_element, find_elements 方法,可以通过 id,class,xpath,等多种方式筛选节点。
对于内联页面,可以通过 switch_to.frame 方法来获取,switch_to.parent_frame 方法来跳出。
同时对于某个特定的节点,可以通过 get_attribute 方法来获取其属性,可以通过 tag_name, id, text 等属性获取其标签名称,id,文本等内容

Q4:如何操作页面

当使用 find_element 找到对应的元素时,可以通过 send_keys, click 等方法完成文本框的输入和按钮的点击。
可以使用 execute_script 方法在当前页面执行 JS 语句,完成一些 api 没有提供的动作,例如下拉页面。

Q5:browser 对象的内部信息总是与网页信息同步吗?

是的,selenium 并不是通过 get 函数或者其它函数来获取页面源代码,而是通过 WebDriver 协议实现的。例如,在每次查找结点 find_element 的时候,都会获取最新的 DOM 状态。

WebDriver 类(Chrome)

from selenium import webdriver

可以用来创建一个浏览器对象,例如,在有 ChromeDriver 的情况下,使用 webdriver.Chrome() 方法可以创建一个 selenium.webdriver.chrome.webdriver.WebDriver 类的对象,即浏览器对象。

该方法在内部会尝试找到 ChromeDriver 可执行文件。ChromeDriver 是一个独立的服务器,它实现了 WebDriver 协议,用于控制 Chrome 浏览器。

selenium 包下的 webdriver 子模块的 __init__.py 文件中又 import 了下级 remote 这个模块中的 webdriver.py 这个模块,所以给了我们一种直接 import 到底层的感觉,其实不是。

返回的 WebDriver 类和上面那个不是同一个类,注意区分。

WebDriver 类(通用版)

get 方法

@params:
url:字符串类型,代表需要访问的网址。将弹出 chrome 浏览器并访问对应网页。

该方法会新建一个标签页

page_source 属性

返回页面源代码。

find_element 方法

@params
By:接受一个 By 类的对象,代表查询方法.
str: 代表具体的值.

例如 By.ID 表示按照元素的 id 属性来查询;字符串代表具体的值,例如可以是 id 属性的值。

返回一个 selenium.webdriver.remote.webelement.WebElement 类的对象, 代表查找到的元素.

如果找不到,会抛出 NoSuchElement 异常。

find_elements 方法

这个方法大致与 find_element 相同,返回的是所有符合条件的元素,因此数据类型是一个列表,列表中的每一项都是 WebElement 对象。

如果找不到,会返回一个空列表。

execute_script 方法

这个方法可以在当前窗口执行 JS 语句,通过 JS 语句就可以完成很多 api 没有提供的功能,例如下滑网页,新建窗口。

@params
str:这个方法可以接受字符串参数,代表需要执行的 JS 语句。

switch_to.frame 方法

内联页面与外部页面的 document tree 时分开的。如果有一个内联页面,是无法用父页面的 selenium 去读取的,需要用该方法先去内联页面中,再访问其节点。

switch_to 方法

由于 @property,因此可以按照属性来使用,返回一个 SwitchTo 类,后者可以通过 frame 方法,接受一个 WebElement 参数或者是对应 iframe 标签的 id 属性的值,来切换到对应的内联页面,同时也可以通过 parent_frame 方法回到父页面。

implicitly_wait 方法

通过该方法可以设定隐式等待的时间,在查找结点而节点没有立即出现时,将会等待一会再去查找,默认等待时间是0。

这个设置会在整个 WebDriver 会话中生效,而不需要为每个元素查找操作单独设置。

@params
int: 代表需要等待的时间,以秒为单位。

forward 方法

该方法可以实现前进

back 方法

该方法可以实现后退

get_cookies 方法

获取当前的 cookies。

window_handles 方法

@property 使其可以像属性一样使用。
@return
list: 返回列表类型的数据,代表当前浏览器选项卡里的所有窗口,每一个窗口都有一个代号,该代号时字符串类型

@return
返回一个列表,列表中的每一项都是一个字典,代表一个 cookie。

向当前的 cookie 列表中加入一个 cookie。

@params
dic: 接受一个字典,代表一个 cookie。

delete_all_cookies 方法

该方法可以删除所有的 cookie。

SwitchTo 类

frame 方法

通过该方法使对应的浏览器对象切换到内联页面

@params
located:接受一个 WebElement 类型或者是字符串类型的参数,代表着内联页面对应标签 iframe 标签的定位,如果传入的是字符串类型的参数,则该参数代表着 iframe 标签的 id 属性的值。

parent_frame 方法

通过该方法使对应的浏览器对象从当前的内联页面切换回父页面。

window 方法

通过这个方法,使得浏览器可以在不同标签页之间切换

@params
str:接受一个字符串类型的参数,代表对应标签页的代号。

By 类

selenium.webdriver.common.by.By

这个类是来定义查找元素的查找方法的,例如当通过 id,xpath 等来寻找单个元素,就可以向 find_element 方法(WebDriver类)中提供参数:By.ID, By.XPATH。

WebElement 类

实际上类中存储的不仅仅是某个 html 结点的信息,还包含了它的子树的信息。因此,再调用查询方法时会查询到其后代的标签。

send_keys 方法

使用这个方法可以往一个输入框里输入字符。

@params:
str: 接受一个字符串类型的参数,表示要输入的值。

clear 方法

使用这个方法可以清空输入框。

click 方法

使用这个方法可以完成点击按钮的操作。

find_elements 方法

@params
By: 接受一个 By 类型的参数,代表筛选方法
str: 接受一个字符串类型的参数,代表筛选方法对应的值,例如 ID 值等等。

返回一个列表,每一项都是 WebElement 对象。
如果找不到合法的,返回空列表。

get_attribute 方法

可以获得某个节点的对应属性。

@params
str:接受一个字符串类型的参数,表示想要获得的属性的名称
@return
str:返回一个字符串类型的参数,表示参数名称对应的值。

text 属性

字符串类型,返回该节点对应的文本内容。

id 属性

字符串类型,返回节点对应的 id

location 属性

返回节点在页面中的相对位置

tag_name 属性

返回节点对应标签的名称

size 属性

返回值类型为字典,节点的宽高,如果要使用宽就用索引 ["width"],如果使用高就用索引 ["height"]

WebDriverWait 类

selenium.webdriver.support.ui

构造函数

@params
WebDriver: 接受一个浏览器对象
int: 代表最大可以等待的时间,以秒为单位。
@return
WebDriverWait:返回一个 WebDriverWait 类实例对象。

until 方法

@params
function:接受一个函数作为参数,这个函数是 expected_conditions.py 中定义的,代表需要满足的条件。
@return
WebElement:如果条件满足,就返回该条件对应的节点。

如果超过设置的最大等待时间,抛出 TimeoutException 异常。

expected_conditions.py 文件

selenium.webdriver.support

该文件下定义了许多函数,代表着显式等待需要满足的条件,服务于 WebDriverWait 类中定义的有关于显式等待的 api。

例如,presence_of_element_located 函数,接受一个参数,参数类型为二元元组,代表着对应节点的定位,例如 (By.ID, "q")

selenium.common.exceptions 模块

这个模块里定义了一些异常

NoSuchElementException 异常

该异常代表没有找到节点。find_element 方法如果没有找到元素就会抛出这个异常。