一、基本操控
下面的代码, 可以自动化的 打开Chrome浏览器,并且自动化打开百度网站,可以大家可以运行一下看看。
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
# 创建 WebDriver 对象,指明使用chrome浏览器驱动
wd = webdriver.Chrome(service=Service(r'd:\tools\chromedriver.exe'))
# 调用WebDriver 对象的get方法 可以让浏览器打开指定网址
wd.get('https://www.baidu.com')
其中,下面这行代码,就会运行浏览器驱动,并且运行Chrome浏览器
wd = webdriver.Chrome(service=Service(r'd:\tools\chromedriver.exe'))
注意,等号右边 返回的是 WebDriver 类型的对象,我们可以通过这个对象来操控浏览器,比如 打开网址、选择界面元素等。
而下面这行代码,就是使用 WebDriver 的 get 方法 打开网址 百度
wd.get('https://www.baidu.com')
执行上面这行代码时,自动化程序就发起了 打开百度网址的 请求消息
,通过浏览器驱动, 给 Chrome浏览器。
Chome浏览器接收到该请求后,就会打开百度网址,通过浏览器驱动, 告诉自动化程序 打开成功。
执行完自动化代码,如果想关闭浏览器窗口可以调用WebDriver对象的 quit 方法,像这样 wd.quit()
省略浏览器驱动路径
前面,我们的代码创建 WebDriver对象时,需要指定浏览器驱动路径,比如
from selenium.webdriver.chrome.service import Service
wd = webdriver.Chrome(service=Service(r'd:\tools\chromedriver.exe'))
这样写有几个问题:
一是,比较麻烦, 每次写自动化代码都 要指定路径。
二是,如果你的代码给别人运行,他的电脑上存放浏览器驱动的路径不一定和你一样(比如他的电脑是苹果Mac电脑),得改脚本。
有什么好办法呢?
我们可以把浏览器驱动 所在目录
加入环境变量 Path
, 写代码时,就可以无需指定浏览器驱动路径了,像下面这样
wd = webdriver.Chrome()
因为,Selenium会自动在环境变量 Path 指定的那些目录里查找名为chromedriver.exe 的文件。
一定要注意的是, 加入环境变量 Path 的,
不是浏览器驱动全路径,比如 d:\tools\chromedriver.exe
而是 浏览器驱动所在目录,比如 d:\tools
而且设置完环境变量后,别忘了重启IDE(比如 PyCharm) 新的环境变量才会生效。
二、选择元素
对于百度搜索页面,如果我们想自动化输入 ,怎么做呢?这就是在网页中,操控界面元素。web界面自动化,要操控元素,首先需要选择界面元素 ,或者说定位界面元素。对应web自动化来说, 就是要告诉浏览器,你要操作的界面元素是什么。可以使用浏览器的开发者工具栏帮我们查看、选择 web 元素。请大家用chrome浏览器访问百度,按F12后,点击下图箭头处的Elements标签,即可查看页面对应的HTML 元素
对于元素的选择有以下几种方法:
1、根据 元素的id 属性选择元素
find_element_by_id和find_elements_by_id(选择多个元素)
查看网页源码,得到搜索文本框的的id为kw
“百度一下”按钮的id为su。编写测试代码,打开百度主页,输入关键字“csdn”。点击百度一下按钮。测试代码如下:
from selenium import webdriver
wd = webdriver.Chrome();
wd.get("https://www.baidu.com")
# 选择搜索文本框
element_text = wd.find_element_by_id('kw')
# 向文本框填入关键字
element_text.send_keys('csdn')
# 选择百度一下按钮
element_submit = wd.find_element_by_id('su')
# 模拟点击按钮
element_submit.click()
其中wd = webdriver.Chrome(),wd 赋值的是 WebDriver 类型的对象,我们可以通过这个对象来操控浏览器,比如 打开网址、选择界面元素等。这里要注意的是浏览器驱动所在的路径需要先包含再windows环境变量path里面,或者把驱动复制到python的安装目录的根目录下也可以(因为python的安装目录已经在环境变量path里面)。否则,需要在函数里面指定驱动的路径,例如chromedriver.exe在d盘根目录下,需要这样写:wd = webdriver.Chrome(r'd:\chromedriver.exe')。
这行代码运行是,就会发起一个请求通过 浏览器驱动 转发给浏览器,告诉它,需要选择一个id为 kw 的元素。找到id为kw的元素后,将结果通过浏览器驱动返回给 自动化程序, 所以 find_element_by_id 方法会 返回一个 WebElement 类型的对象。这个WebElement 对象可以看成是对应 页面元素 的遥控器。我们通过这个WebElement对象,就可以 操控 对应的界面元素。
比如 :调用这个对象的 send_keys 方法就可以在对应的元素中输入字符串,调用这个对象的 click 方法就可以 点击 该元素。
2、根据 class属性 选择元素
web自动化的难点和重点之一,就是如何 选择 我们想要操作的web页面元素。除了根据元素的id ,我们还可以根据元素的 class 属性选择元素。如一网页,源码如下:
<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>
所有的植物元素都有个class属性 值为 plant。
所有的动物元素都有个class属性 值为 animal。
如果我们要选择 所有的 动物, 就可以使用方法 find_elements_by_class_name 。
注意element后面多了个s
wd.find_elements_by_class_name('animal')
find_elements_by_class_name 方法返回的是找到的符合条件的 所有 元素 (这里有3个元素), 放在一个 列表 中返回。而如果我们使用 find_element_by_class_name (注意少了一个s) 方法, 就只会返回 第一个 元素。大家可以运行如下代码看看。
from selenium import webdriver
# 创建 WebDriver 实例对象,指明使用chrome浏览器驱动
wd = webdriver.Chrome()
# WebDriver 实例对象的get方法 可以让浏览器打开指定网址
wd.get('http://cdn1.python3.vip/files/selenium/sample1.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)
首先,大家要注意: 通过 WebElement 对象的 text属性 可以获取该元素 在网页中的文本内容。
所以 下面的代码,可以打印出 element 对应 网页元素的 文本
print(element.text)
如果我们把
elements = wd.find_elements_by_class_name('animal')
去掉一个s ,改为
element = wd.find_element_by_class_name('animal')
print(element.text)
那么返回的就是第一个class 属性为 animal的元素, 也就是这个元素
<div class="animal"><span>狮子</span></div>
3、根据 tag 名 选择元素
类似的,我们可以通过方法 find_elements_by_tag_name ,选择所有的tag名为 div的元素,如下所示:
from selenium import webdriver
wd = webdriver.Chrome()
wd.get('http://cdn1.python3.vip/files/selenium/sample1.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、通过WebElement对象选择元素
不仅 WebDriver对象有 选择元素 的方法, WebElement对象 也有选择元素的方法。
WebElement对象 也可以调用 find_elements_by_xxx, find_element_by_xxx 之类的方法
WebDriver 对象 选择元素的范围是 整个 web页面,而WebElement 对象 选择元素的范围是 该元素的内部。
from selenium import webdriver
wd = webdriver.Chrome()
wd.get('http://cdn1.python3.vip/files/selenium/sample1.html')
element = wd.find_element_by_id('container')
# 限制 选择元素的范围是 id 为 container 元素的内部。
spans = element.find_elements_by_tag_name('span')
for span in spans:
print(span.text)
三、操控元素
1、点击元素
点击元素 非常简单,就是调用元素WebElement对象的 click方法。前面我们已经学过。
2、在输入框输入文本或清除文本
输入文本:就是调用元素WebElement对象的send_keys方法。前面我们也已经学过
清除文本:可以使用WebElement对象的clear方法
3、获取元素信息
作用 | 方法 |
获取元素的文本内容 | WebElement对象的 text 属性,例print(element.text) |
获取元素属性 | WebElement对象的 get_attribute 方法来获取元素的属性值, 例element.get_attribute('class') |
获取整个元素对应的HTML | element.get_attribute('outerHTML') 如果,只是想获取某个元素 内部 的HTML文本内容,可以使用 element.get_attribute('innerHTML') |
获取输入框里面的文字 | 对于input输入框的元素,要获取里面的输入文本,用text属性 是不行的,这时可以使用 element.get_attribute('value') |
获取元素文本内容2 | 讲过WebElement对象的 text 属性,可以获取元素 展示在界面上的 文本内容。但是,有时候,元素的文本内容没有展示在界面上,或者 没有完全完全展示在界面上。 这时,用WebElement对象的text属性, 获取文本内容,就会有问题。出现这种情况,可以尝试使用 element.get_attribute('innerText') ,或者 element.get_attribute('textContent') |
4、鼠标右击、双击、移动到元素上方、拖拽等操作
Selenium 提供的 ActionChains 类来实现。
ActionChains 类 里面提供了 一些特殊的动作的模拟,我们可以通过 ActionChains 类的代码查看到