安装
pip install selenium
安装对应的浏览器驱动版本
自行查找,selenium是完全支持edge,firefox, chrome的
需要查看本机浏览器的版本号
页面元素的定位
前提
进入浏览器的指定页面,按F12进入开发者工具,选择选取页面元素。
from selenium import webdriver
"""
防止浏览器自动关闭
option = webdriver.FirefoxOptions()
option.add_experimental_optiond("detach", True)
driver = webdriver.Firefox(Firefox_option=option)
"""
#Firefox
driver = webdriver.Firefox()#实例化浏览器对象
driver.get(url)
八种元素定位方式
id定位
标签的id具有唯一性。
from selenium.webdriver.common.by import By
#定位前需要导入By
#原先的driver.find_element_by_name()方式已经弃用了
#新方式
driver.find_element(By.ID,'id的内容')
name定位
name指顶标签的名称,在一个页面中并不是唯一的,有重复性,不推荐使用。
driver.find_element(By.NAME,'name的内容')
class定位
class指定标签的类名,在页面中也可能是不唯一的。
driver.find_element(By.CLASS_NAME,'class的内容')
tag定位
tag往往用来定义一类功能,所以通过tag来定位元素的成功率很低。
driver.find_element(By.TAG_NAME,'tag的内容(如:div,input等)')
xpath定位
xpath是在XML文件中定位元素的一种语言,定位的方式并不唯一。可以直接通过浏览器的开发者工具来copy某一元素的xpath
driver.find_element(By.XPATH,'复制来的xpath')
css定位
css使用选择器来为页面元素绑定属性,可以较为灵活的选择控件的任意属性,一般定位的速度要比xpath快。
同样可以使用浏览器的开发者工具来直接copy
driver.find_element(By.CSS_SELECTOR,'复制的css')
link定位
link专门用来定位文本链接。
#例如定位如下标签
<div class="practice-box" data-v-04f46969="">加入!每日一练</div>
driver.find_element(By.LINK_TEXT,'加入!每日一练')
partial_link定位
partial_link意为”部分链接“,对某些很长的文本链接,可以只指定部分文本即可定位
#借用link定位里的例子:
driver.find_element(By.PARTIAL_LINK_TEXT,'加入')
浏览器的控制
修改浏览器的窗口大小
from selenium import webdriver
#Firefox
driver = webdriver.Firefox()
driver.get('http://www.baidu.com')
driver.set_window_size(600,800)#设置窗口大小
"""
也可用maximize_window()方法实现浏览器窗口最大化
driver.maximize_window()
"""
浏览器的前进与后退
webdriver提供了back和forward方法来实现页面的后退与前进。
from selenium import webdriver
#例如:在首页点击入一个页面之后,想回退到首页
driver.back()
#再想从首页进入之前那个页面
driver.forward()
进入网站首页时,再调用get方法来进入子页面。
#两种方法
#原页面打开
driver.get('')
#新建标签页打开
js = "window.open('')"
driver.execute_script(js)
浏览器刷新
某些时候,需要刷新浏览器页面来获取最新数据。
#webdriver提供refresh()方法来刷新
dirver.refresh()
浏览器的窗口切换
很多时候需要切换窗口,比如注册时,会生成一个注册页面,未进行切换时是无法定位到注册页面的元素的。切换窗口可以通过获取窗口的句柄来实现,该信息是按照时间顺序来的,最新的窗口,句柄存放在数组末尾,即索引为-1的位置。
#获取已打开的多窗口句柄
windows = driver.window_handles
#切换到当前最新打开的窗口
driver.switch_to.window(window[-1])
其他常见操作
| 方法名 | 作用 |
|---|---|
send_keys() | 模拟输入,内容即为括号里的内容 |
clear() | 清楚文本内容 |
is_displayed() | 判断该元素是否可见 |
get_attribute() | 获取标签属性的内容 |
size | 返回元素尺寸 |
text | 返回元素文本 |
控制鼠标
在webdriver中,控制鼠标的方法都封装在ActionChains类中,较为常用的方法如下:
| 方法 | 描述 |
|---|---|
click() | 单击左键 |
context_click() | 单击右键 |
double_click() | 双击 |
drag_and_drop() | 拖动 |
movoe_to_element | 鼠标悬停 |
perform() | 执行所有ActionChains中存储的动作 |
单击左键
单击左键不需要用到ActionChains类
#定位要点击的元素位置
button = driver.find_element(By.XPATH,'位置')
#调用click()方法即可完成点击
button.click()
单击右键
需要用到ActionChains类
#定位点击元素的位置(同上)
#右键点击
ActionChains(driver).context_click(button).perform()
双击
#直接写怎么点击
ActionChains(driver).double_click(button).perform()
拖动
该操作必须要有两个参数,一是要拖动的元素位置,二是将要拖动到的元素。
#被拖动的元素
source = driver.find_element(By.XPATH,'xxx')
#目标元素
target = driver.find_element(By.XPATH,'xxx')
#执行拖动的动作
ActionChains(driver).drag_and_drop(source, target).perform()
鼠标悬停
鼠标悬停是为了显示隐藏的下拉框,例如优快云主页的收藏栏。
#定位要悬停的元素
#执行鼠标悬停操作
ActionChains(driver).move_to_element(element).perform()
控制键盘
webdriver中的keys类几乎提供了键盘上的所有按键方法,使用send_keys + Keys来实现输出键盘上的组合按键。
from selenium.webdriver.common.keys import Keys
#定位输入框并输入文本
driver.find_element(By.XPATH,'xxx').send_keys('text')
#模拟回车(输入内容之后)
driver.find_element(By.XPATH,'xxx').send_keys(Keys.ENTER)
#模拟Backspace删除一个字符
.send_keys(Keys.BACK_SPACE)
………………………………
列举一些,不细说,基本思路就是Keys.不同格式的大写键名
设置元素等待
因为很多页面都使用ajax技术,页面的元素不是同时被加载的,为防止定位这些尚在加载的元素出错,可以设置元素等待来增加脚本的稳定性。
webdriver有显式等待和隐式等待两种。
显式等待
原理:设置一个超时时间,然后每隔一段时间就检测一次某元素是否存在,存在则执行后续语句,如果时间超过超时时间,该元素还不存在则抛出超时异常TimeoutException.
WebDriverWait(driver, timeout, poll_frequency=n, ignored_exception=None).until(method, message='') or .until_not(method, message='')
driver:浏览器驱动对象timeout:超时时间,单位为秒poll_frequency:检测的间隔时间,默认为0.5秒ignored_exception:指定忽略的异常,如果在调用until或者until_not的过程中抛出指定忽略的异常,则不中断代码。默认忽略NoSuchElementExceptionmethod:指定预期条件的判断方法,在等待期间,每隔指定的间隔时间,就调用该方法来判断元素是否存在,直到元素出现。until_not正好相反,当元素消失或指定条件不成立,则继续执行后续代码。message:如果出现超时,抛出TimeoutException的同时,显示message的内容。
method中的预期条件判断方法是由expected_conditions提供的。
定位器:
locator = (By.XPATH, 'xxx')
expected_conditions提供很多判断方法。
title_is(text):判断当前页面的title是否为texttitle_contains(text):判断当前页面的title是否包含text- ………………
简单例子:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
driver = webdriver.Firefox()
element = WebDriverWait(driver, 5, 0.5).until(EC.title_is(text)), message='Already timeout!')
隐式等待
隐式等待也是指定一个超时时间,与显示等待不同是,如果超出这个指定时间时,元素还没被加载出来,抛出的是NoSuchElementException异常。
此外,隐式等待是全局性的,即运行过程中,如果元素可以找到,不会影响代码的运行,如果找不到,则会以轮询的方式不断的访问元素直到元素被找到或者超时抛出异常。
implicitly_wait()来实现隐式等待。
示例:打开页面,设置隐式等待时间为5s,通过d定位一个不存在的元素,最后打印抛出的异常与运行时间。
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import time
driver = webdriver.Firefox()
driver.get('xxx')
start = time()
driver.implicilty_wait(5)
try:
driver.find_element(By.ID,'kw')
except Exception as e:
print(e)
print(f'spend:{time()-start}')
代码运行到driver.find_element(By.ID,'kw')这句之后触发隐式等待,在轮询检查5s后,仍旧没有定位到元素,就抛出异常。
强制等待
即通过time.sleep()来强制等待页面加载。比较死板,会影响代码的运行效率。
定位一组元素
即将之前定位元素的8种方法中的element改为```elements``即可。
切换
表单切换
很多页面会用带frame/iframe表单嵌套,对于这种内嵌的页面,无法直接定位,需要使用switch_to.frame()来切换。
可以直接通过id、name来进行切换。
弹窗处理
JavaScript有三种弹窗alert(确认)、confirm(确认、取消)、prompt(文本框、确认、取消)。
处理的方式:首先定位弹窗(switch_to.alert自动获取当前弹窗),再使用以下方法进行操作:
| 方法 | 描述 |
|---|---|
text | 获取弹窗种的文字 |
accept | 确认弹窗内容 |
dismiss | 取消弹窗 |
send_keys | 发送文本至警告框 |
其他操作
关闭浏览器
driver.quit()
关闭当前页面
driver.close()
对当前页面进行截图
主要用在测试时记录报错页面。结合try except来使用。
try:
driver.find_element(By.XPATH,'xxx').click()
except:
driver.get_screenshot_as_file(r'path&name')
常用方法总结
# 获取当前页面url
driver.current_url
# 获取当前html源码
driver.page_source
# 获取当前页面标题
driver.title
# 获取浏览器名称
driver.name
# 对页面进行截图,返回二进制数据
driver.get_screenshot_as_png()
# 设置浏览器尺寸
driver.get_window_size()
# 获取浏览器尺寸,位置
driver.get_window_rect()
# 获取浏览器位置(左上角)
driver.get_window_position()
# 设置浏览器尺寸
driver.set_window_size(width=1000, height=600)
# 设置浏览器位置(左上角)
driver.set_window_position(x=500, y=600)
# 设置浏览器的尺寸,位置
driver.set_window_rect(x=200, y=400, width=1000, height=600)
1万+

被折叠的 条评论
为什么被折叠?



