一、环境准备
1、首先、在pycharm中安装工具
pip install selenium -i https://pypi.tuna.tsinghua.edu.cn/simple
2、在我的浏览器(谷歌,版本86)中安装插件驱动WebDriver
,下载插件地址
2、1驱动下载后解压放到python解释器的安装目录即可(我的解释器安装在下面位置)
二、页面元素的定位方式
2.1、简单方式
通过 id 属性定位 : find_element_by_id
通过 name 属性定位 : find_element_by_name
通过 class 属性定位 : find_element_by_class_name
通过标签名定位 : find_element_by_tag_name
通过内容定位 a 标签(绝对匹配) : find_element_by_link_text
通过内容定位 a 标签(模糊匹配) : find_element_by_partial_link_text
代码示例
固定写法:file://{本地文件绝对路径}
"""
步骤:
1. 创建驱动对象
2. 打开测试网址
3. 找元素
4. 做后续操作
5. 关闭浏览器
"""
from selenium.webdriver import Chrome
import time
import traceback
# 1. 创建驱动对象
driver = Chrome()
# file://{本地文件绝对路径}
# 比如我的是Windows本地路径有一个自制的html页面
driver.get('file://F:/test/selenium/test.html')
# 真是存在的url也可,如百度url
# driver.get('https://www.baidu.com')
try:
# 如果找到,返回对象,没有找到,抛出异常NoSuchElementException
el = driver.find_element_by_id('username')
time.sleep(2)
except Exception as e:
# 产生异常后执行
# print(e)
print(traceback.format_exc()) # 异常过程信息可以打印
finally:
# 不管有没有异常,都会执行
driver.quit()
2.2 xpath定位方式
如果找到,返回对象;没有找到,抛出异常NoSuchElementException
# 绝对路径
driver.find_element_by_xpath('/html/body/form/input')
# 相对路径
driver.find_element_by_xpath('//body/form/input')
# 结合属性
driver.find_element_by_xpath('//form/input[@type="text"]')
# 满足多个属性
driver.find_element_by_xpath('//form/input[@type="text" and @name="username"]')
# 指定元素的上一级路径
driver.find_element_by_xpath('//form/input/..')
el = driver.find_element_by_xpath('//ul/li') # 默认是第1个(如果li标签有多个)
print(el) # 得到一个列表
el = driver.find_element_by_xpath('//ul/li[1]') # 取第1个
el = driver.find_element_by_xpath('//ul/li[last()]') # 取最后一个
el = driver.find_element_by_xpath('//ul/li[last()-1]') # 取倒数第二个
2.3 CSS定位方式
如果找到,返回对象;没有找到,抛出异常NoSuchElementException
# id="username", 通过id,‘#’号
driver.find_element_by_css_selector('#username')
# class="input-password", 通过class,‘.’号
driver.find_element_by_css_selector('.input-password')
# 通过标签元素
driver.find_element_by_css_selector("form")
# 通过属性, 和xpath区别,没有@
driver.find_element_by_css_selector('input[type="text"]')
# 取父节点为ul下的li标签
driver.find_element_by_css_selector("ul>li")
2.4 find_element
语法:find_element(By.ID, 'username')
# find_element主要用于二次封装使用
# 参数1:为定位元素方式,参数2:定位元素的实现字符串,和以前用法一样
"""
class By(object):
ID = "id"
XPATH = "xpath"
LINK_TEXT = "link text"
PARTIAL_LINK_TEXT = "partial link text"
NAME = "name"
TAG_NAME = "tag name"
CLASS_NAME = "class name"
CSS_SELECTOR = "css selector"
"""
# driver.find_element_by_id()
# By通过快捷键导包
el = driver.find_element(By.ID, 'username')
print(el)
2.5 查询多个元素
- 方法名:
find_elements()
(element多一个s) - 返回值:
- 找到:包含找到元素对象的列表
- 没有找到:返回空列表
语法:find_elements(By.ID, 'username')
三、元素等待
问题引入:
如果页面没有加载完成就定位元素,会找不到这个元素
三种解决方法:
(1)强制等待:
time.sleep():简单粗暴,指定时间等待,就算网页提前加载完,也必须等待指定的时间
(2)显式等待:
指定时间等待,指定时间没有加载完成,不等了
提前加载完成,也不等了
特点:只能设置`等待指定的元素`,写法麻烦,效率高
显式等待使用:
"""
1. 创建WebDriverWait对象,指定等待时间
2. 语法:WebDriverWait对象.until()设置等待的元素
2.1 until()传入是一个函数名,这个函数有一个参数,这个参数是Chrome类型
2.2 上一步中的2.1函数体返回定位元素的对象
2.3 WebDriverWait对象.until()返回值就是定位到的对象
参数1:驱动对象,参数2:设置等待时间,
参数3:没有找到,自动调用调用wait_driver.until()指定的函数时间
返回值:对象
TimeoutException: 指定时间没有找到,抛出异常
如果元素没有找到,会自动调用wait_driver.until()指定的函数
"""
wait_driver = WebDriverWait(driver, 10)
# 语法:wait_driver对象.until(函数名)
el = wait_driver.until(lambda foo: foo.find_element_by_tag_name('html'))
显示等待的封装方法:
from selenium.webdriver import Chrome
import time
import traceback
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
# 1. 创建驱动对象
driver = Chrome()
# file://{本地文件绝对路径}
driver.get('file:///Users/mikejiang/Desktop/code/selenium_code/test.html')
def find_w_element(by=By.ID, value=None, _t=10):
wait_driver = WebDriverWait(driver, _t)
el = wait_driver.until(lambda temp_driver: temp_driver.find_element(by, value))
return el
def find_w_element_by_xpath(xpath, _t=10):
wait_driver = WebDriverWait(driver, _t)
el = wait_driver.until(lambda temp_driver: temp_driver.find_element_by_xpath(xpath))
return el
try:
el = find_w_element(By.ID, 'username')
print(el)
el = find_w_element_by_xpath('//form/input')
print(el)
except Exception as e:
# 产生异常后执行
# print(e)
print(traceback.format_exc()) # 异常过程信息可以打印
finally:
# 不管有没有异常,都会执行
driver.quit()
(3)隐式等待
指定时间等待,指定时间没有加载完成,不等了
提前加载完成,也不等了
特点:等待`整个页面加载完`,写法简单,效率低
使用:在一开始创建驱动对象的时候设置:`driver.implicitly_wait(10) # 设置等待时间`
四、常用的属性和方法
4.1浏览器
常用的属性和方法
4.1.1属性
driver.name # 当前浏览器的名字
driver.title # 当前网页的标题
driver.page_source # 当前网页的源码
driver.current_url # 当前的url
# 如果页面没有最大化,元素可能被遮挡,这时候定位元素会失败
# 每切换一个页面,页面恢复原来的页面的尺寸(比如原来是窗口化,使用最大化命令后,切换窗口后会恢复窗口化)
driver.maximize_window() # 最大化
driver.fullscreen_window() # 全屏
4.1.2方法
driver.close() # 关闭当前窗口
driver.quit() # 关闭浏览器
# 历史
driver.back() # 历史后退
driver.forward() # 历史前进
# 刷新页面
driver.refresh() # 刷新页面
# 窗口大小位置
driver.maximize_window() # 浏览器最大化
driver.fullscreen_window() # 浏览器全屏
driver.minimize_window() # 浏览器最小化
4.1.3窗口截图(抛异常的时候才会截图)
# 1. 截图操作应该放在except捕获异常那里
# 2. 页面出错后,截图页面,方便后面定位错误
# 3. 截图,是截运行的浏览器页面
driver.get_screenshot_as_file('xxx.png')
4.1.4 执行JavaScript代码
# 弹出对话框
# driver.execute_script(js代码)
driver.execute_script('alert("警告,停止访问")')
4.1.5 cookie相关操作
driver.get_cookies() # 获取所有的 cookie
driver.get_cookie(name) # 获取指定的 cookie
driver.delete_cookie(name) # 删除指定的 cookie
driver.delete_all_cookies() # 删除所有的 cookie
driver.add_cookie(cookie_dict) # 添加一个 cookie cookie_dict = {"name":"xxx","value":"xxx"} key 为 "path", "domain", "secure", "expiry"的可设可不设
4.2 元素
常用的属性和方法
4.2.2 鼠标
鼠标单击:元素对象.click()
# 1. 先找button元素对象
el = driver.find_element_by_id('button')
# 点击10次
for _ in range(10):
el.click()
time.sleep(0.5)
鼠标的其他用法:
reset_actions(self) : 清空行为链
click(self, on_element=None): 鼠标点击
click_and_hold(self, on_element=None) : 鼠标按下
release(self, on_element=None) : 松开鼠标
context_click(self, on_element=None) : 鼠标右击
double_click(self, on_element=None) : 鼠标双击
drag_and_drop(self, source, target) : 拖动元素,source 被拖动元素,target 表示被拖动到那个元素中
drag_and_drop_by_offset(self, source, xoffset, yoffset) : 拖动元素,给定x,y 轴偏移
key_down(self, value, element=None) : 按键按下
key_up(self, value, element=None) : 按键松开
move_by_offset(self, xoffset, yoffset) : 鼠标箭头移动,给定 x,y 轴偏移
move_to_element(self, to_element) : 鼠标移动到某个元素中心
move_to_element_with_offset(self, to_element, xoffset, yoffset) : 鼠标移动到元素内的 x,y 轴位置
send_keys(self, *keys_to_send): 发送多个按键,也可以是一个字符串
send_keys_to_element(self, element, *keys_to_send) :
4.2.2 输入框元素填充和清空
# 1. 先找button元素对象
el = driver.find_element_by_id('username')
time.sleep(1)
el.send_keys('mike帅吗?') # 输入
time.sleep(2)
el.clear() # 清空
time.sleep(1)
el.send_keys('不帅!!!')
time.sleep(1)
4.2.3 获取标签的属性
1、
元素对象.text
: 获取元素对象上的文本内容,标签上有内容才有效
2、元素对象.get_attribute('innerHTML')
获取标签上的内置的html代码,get_attribute也可以获取其它属性
4.2.4 行为链(以在输入框输入一个大写字母A为例)
from selenium.webdriver import Chrome
import traceback
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
import time
# 通过指定chromedriver的路径来实例化driver对象
driver = Chrome()
# 控制浏览器访问url地址
# file://{本地文件绝对路径}
driver.get('file://F:/test/selenium/test.html') # 打开本地 html 文件
# 实例化 ActionChains 对象
actions = ActionChains(driver)
try:
# 找到输入框元素
input_el = driver.find_element_by_id('username')
# 鼠标移动到表单元素上-->执行点击-->按下shift-->按下 a -->松开 shift-->松开 a
# 相当于给输入框驶入一个字母 A
actions.move_to_element(input_el).click().key_down(Keys.SHIFT).key_down('a').key_up(Keys.SHIFT).key_up('a')
# 执行行为链
actions.perform()
time.sleep(2)
except Exception as e:
print(traceback.format_exc())
finally:
# 退出浏览器
driver.quit()
五、frame、窗口、警告框
5.1 frame框架
driver.get('https://www.w3school.com.cn/tiy/t.asp?f=html_elements_select')
try:
# 1. 找iframe元素,在外页面找
el_frame = driver.find_element_by_css_selector("iframe")
# 2. 切换到frame里面
# driver.switch_to.frame(frame元素)
driver.switch_to.frame(el_frame)
# 3. 在里面找所需的元素
el = driver.find_element_by_css_selector('select')
print(el.get_attribute('innerHTML'))
5.2 多窗口切换
from selenium.webdriver import Chrome
import traceback
import time
# 1. 创建驱动对象
driver = Chrome()
# file://{本地文件绝对路径}
driver.get('https://www.baidu.com')
try:
# 0. 获取当前窗口的句柄
print(driver.current_window_handle) # 首页
# 1. 打开百度首页的新闻,点击
driver.find_element_by_link_text('新闻').click()
# 1.1 获取自动点击后的窗口(新闻)的句柄
print(driver.current_window_handle)
# 结论:依然是首页的句柄,不会因为点击后切换到新的窗口而改变句柄
# 所以需要切换句柄(窗口)
# 2. 获取窗口所有的句柄(新开一个页面,有2个句柄)
print(driver.window_handles)
# 3. 切换
time.sleep(1)
driver.switch_to.window(driver.window_handles[1]) # 切换到新闻的页面
time.sleep(1)
driver.switch_to.window(driver.window_handles[0]) # 百度首页
time.sleep(1)
driver.switch_to.window(driver.window_handles[1]) # 新闻页面
except Exception as e:
# 产生异常后执行
# print(e)
print(traceback.format_exc()) # option 异常过程信息可以打印
finally:
# 不管有没有异常,都会执行
driver.quit()
5.3 警告框的处理
和之前的frame一样,也需要先切换到另外的窗口(警告框)才能操作。
# 1. 弹出一个警告框
driver.execute_script('alert("hello mike")')
time.sleep(2)
# 2. 切换到警告框
alert = driver.switch_to.alert
time.sleep(1)
# 3. 关闭警告框
alert.dismiss() # 关闭
alert.accept() # 接收
六、下拉框的处理
Select类:
from selenium.webdriver.support.select import Select
说明:Select 类是 WebDriver 为解决 select 标签定位诞生的,此类定位的是 select 标签。
使用步骤:
- (1)找到这个下拉框元素
- (2)创建一个select类的对象
- (3)对象可以对下拉框进行一些操作
# 1. 找下拉框元素
el = driver.find_element_by_id('select-multiple')
# 2. 创建专属类型的对象
sel_obj = Select(el)
# 3. 操作
print(sel_obj.options) # 查看下拉框内容
print(len(sel_obj.options)) # 查看下拉框个数
time.sleep(1)
# 通过下拉框内容的下标进行选中
for i in range(len(sel_obj.options)):
sel_obj.select_by_index(i)
time.sleep(1)
下拉框的其他一些操作:
select.options # select 中所有 options
select.all_selected_options # 所有被选中的 option
select.first_selected_option # 第一个被选中的 option
select.select_by_value(value) # 通过 option 的值选中
select.select_by_index(index) # 通过 option 的下标选中
select.select_by_visible_text(text) # 通过 option 的可见文本选中
select.deselect_all() # 全部不选中
select.deselect_by_value(value) # 通过 option 的值取消选中
select.deselect_by_index(index) # 通过 option 的下标取消选中
select.deselect_by_visible_text(text) # 通过 option 的文本取消选中
七、无界面模式
当我们进行一些自动化操作过程中,很多时候都不需要看到电脑在自动切换画面进行操作,而是让它在后台运行,最后给出我们结果就好。因此我们可以将程序设置成无界面模式.
在一开始创建驱动对象的时候,进行如下配置即可:
# 1. 创建配置对象
opt = ChromeOptions()
# 2. 添加选项
opt.add_argument('--headless')
opt.add_argument('--disable-gpu')
# 3. 创建驱动对象, 指定配置选项信息
driver = Chrome(options=opt)