一、原理
Selenium 是一个 Web 应用的自动化框架。
通过它,我们可以写出自动化程序,像人一样在浏览器里操作web界面。 比如点击界面按钮,在文本框中输入文字 等操作,而且还能从web界面获取信息。
Selenium 的自动化原理如图所示:
从上图可以看出:
编写的自动化程序 需要使用 客户端库,程序的自动化请求都是通过这个库里面的编程接口发送给浏览器。比如,要模拟用户点击界面按钮, 自动化程序里面就应该 调用客户端库相应的函数, 就会发送 点击元素 的请求给 下方的 浏览器驱动。 然后,浏览器驱动再转发这个请求给浏览器(自动化程序发送给浏览器驱动的请求 是HTTP请求)
浏览器驱动 也是一个独立的程序,是由浏览器厂商提供的, 不同的浏览器需要不同的浏览器驱动。 比如 Chrome浏览器和 火狐浏览器有 各自不同的驱动程序。
浏览器驱动接收到我们的自动化程序发送的界面操作请求后,会转发请求给浏览器, 让浏览器去执行对应的自动化操作。浏览器执行完操作后,会将自动化的结果返回给浏览器驱动, 浏览器驱动再通过HTTP响应的消息返回给我们的自动化程序的客户端库。自动化程序的客户端库 接收到响应后,将结果转化为 数据对象 返回给 我们的代码。
总而言之,selenium 自动化流程如下:
- 自动化程序调用Selenium 客户端库函数(比如点击按钮元素) 客户端库会发送Selenium 命令 给浏览器的驱动程序
- 浏览器驱动程序接收到命令后 ,驱动浏览器去执行命令 浏览器执行命令 浏览器驱动程序获取命令执行的结果,返回给自动化程序
- 自动化程序对返回结果进行处理
二、安装
1、安装客户端库
pip install selenium
2、安装浏览器驱动
浏览器驱动 是和 浏览器对应的。 不同的浏览器 需要选择不同的浏览器驱动,以谷歌浏览器为例:
Chrome 浏览器驱动下载地址:https://chromedriver.storage.googleapis.com/index.html
三、简单实例
from selenium import webdriver
# 创建 WebDriver 对象,指明使用chrome浏览器驱动
wd = webdriver.Chrome(r'd:\webdrivers\chromedriver.exe')
# 调用WebDriver 对象的get方法 可以让浏览器打开指定网址
wd.get('https://www.baidu.com')
将浏览器驱动目录加入到环境变量Path中:
如上代码所示,创建WebDriver对象时,需要指定浏览器驱动路径,但如果将浏览器驱动 所在目录加入环境变量Path,再写代码的时候,就可以无需指定浏览器驱动路径,如:
wd = webdriver.Chrome()
因为,Selenium会自动在环境变量 Path 指定的那些目录里查找名为chromedriver.exe 的文件
一定要注意的是, 加入环境变量 Path 的,不是浏览器驱动全路径,比如 d:\webdrivers\chromedriver.exe
而是 浏览器驱动所在目录,比如 d:\webdrivers
执行脚本出现如图所示字样,则证明环境配置成功,可以开始编写代码了
上面是win10系统环境变量配置,如果是Mac,请移步mac 下 selenium无法启动浏览器
四、选择元素
1、根据元素id属性选择元素
id 可以想象成元素的编号, 用来在html中标记该元素的。 根据规范, 如果元素有id属性 ,这个id 必须是当前html中唯一的,所以如果有id,根据id选择元素是最简单的方式,如下图所示,可以看到 百度搜素框 元素的id为 kw
所以如下代码示例:
from selenium import webdriver
# 创建 WebDriver 对象,指明使用chrome浏览器驱动
wd = webdriver.Chrome(r'd:\webdrivers\chromedriver.exe')
# 调用WebDriver 对象的get方法 可以让浏览器打开指定网址
wd.get('https://www.baidu.com')
# 根据id选择元素,返回的就是该元素对应的WebElement对象
element = wd.find_element_by_id('kw')
# 通过该 WebElement对象,就可以对页面元素进行操作了
# 比如输入字符串到 这个 输入框里
element.send_keys('python\n')
【注意】
send_keys 方法按照字面意思 即 可以在对应的元素中 输入字符串
click 方法按照字面意思 即 可以 点击 该元素
2、根据class属性、tag名 选择元素
就像一个 学生张三 可以定义类型为 中国人 或者 学生一样, 中国人 和 学生 都是 张三 的 类型。元素也有类型, class 属性就用来标志着元素 类型
【注意】
find_elements_by_class_name 方法返回的是找到的符合条件的 所有 元素 (这里有3个元素), 放在一个 列表 中返回,如果没有符合条件的元素, 返回空列表
而如果我们使用 find_element_by_class_name (注意少了一个s) 方法, 就只会返回 第一个 元素,如果没有符合条件的元素,会抛出NoSuchElementException 异常
<body>
<div class="plant"><span>土豆</span></div>
<div class="plant"><span>西红柿</span></div>
<div class="plant"><span>南瓜</span></div>
<div class="animal"><span>大狮子</span></div>
<div class="animal"><span>大老虎</span></div>
<div class="animal"><span>花蝴蝶</span></div>
</body>
以上面所示页面为例,通过WebElement 对象的 text属性 可以获取该元素在网页中的文本内容,如下面代码所示的for循环,会输出所有动物的名称
from selenium import webdriver
# 创建 WebDriver 实例对象,指明使用chrome浏览器驱动
wd = webdriver.Chrome(r'd:\webdrivers\chromedriver.exe')
# WebDriver 实例对象的get方法 可以让浏览器打开指定网址
wd.get('http://xxxxx.html')
# 根据 class name 选择元素,返回的是 一个列表
# 里面 都是class 属性值为 animal的元素对应的 WebElement对象
elements = wd.find_elements_by_class_name('animal')
# 取出列表中的每个 WebElement对象,打印出其text属性的值
# text属性就是该 WebElement对象对应的元素在网页中的文本内容
for element in elements:
print(element.text)
【注意】
元素也可以有 多个class类型 ,多个class类型的值之间用 空格 隔开,比如
<span class="chinese student">张三</span>
这里 span元素 有两个class属性,分别 是 chinese 和 student, 而不是一个 名为 chinese student 的属性,如果要用代码选择这个元素,可以指定任意一个class 属性值,都可以选择到这个元素,如下
element = wd.find_elements_by_class_name('chinese')
或者
element = wd.find_elements_by_class_name('student')
而不能这样写
element = wd.find_elements_by_class_name('chinese student')~
3、根据tag名选择元素
可以通过方法 find_elements_by_tag_name ,选择所有的tag名为 div的元素,如下所示
from selenium import webdriver
wd = webdriver.Chrome(r'd:\webdrivers\chromedriver.exe')
wd.get('http://xxxxx.html')
# 根据 tag name 选择元素,返回的是 一个列表
# 里面 都是 tag 名为 div 的元素对应的 WebElement对象
elements = wd.find_elements_by_tag_name('div')
# 取出列表中的每个 WebElement对象,打印出其text属性的值
# text属性就是该 WebElement对象对应的元素在网页中的文本内容
for element in elements:
print(element.text)
4、根据 link text 对象 选择超链接元素
from selenium import webdriver
from selenium.webdriver.com