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。
add_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 方法如果没有找到元素就会抛出这个异常。