selenium
Selenium
Se enium 一个 自动化测试工具,利用它可以驱动浏览器执行特定的动作,如点击、下拉等操作,同时还可以获取浏览器当前呈现的页面的源代码 ,做到可见即可爬。
参考文档:
1. 安装
参考文档:
2. 快速入门
参考文档:
使用步骤:
- 导包
- 初始化浏览器对象
- 请求页面
- 与页面交互
- 关闭浏览器对象
3. 初始化浏览器对象
Se lenium 支持非常多的浏览器,如 hrome Firefox dge ,还有 Android Black.Berry 等手机端的浏览器。另外,也支持无界面浏览器 PhantomJS。
webdriver.Firefox
webdriver.FirefoxProfile
webdriver.Chrome
webdriver.ChromeOptions
webdriver.Ie
webdriver.Opera
webdriver.PhantomJS
webdriver.Remote
webdriver.DesiredCapabilities
webdriver.ActionChains
webdriver.TouchActions
webdriver.Proxy
这样就完成了浏览器对象的初始化并将其赋值为 browser 接下来,我 要做的就是调用 browser 对象,让其执行各个动作以模拟浏览器操作。
4. 请求页面
可以用 get()方法来请求网页,参数传入链接 URL 即可。
driver.get("http://www.google.com")
5. 与页面交互
我们比较喜欢做的事情就是和页面交互,准确的说,是和页面里的HTML元素交互。
5.1. 查找元素
详情查看:https://selenium-python-zh.readthedocs.io/en/latest/locating-elements.html
https://python-selenium-zh.readthedocs.io/zh_CN/latest/4.元素定位/
在一个页面中有很多不同的策略可以定位一个元素。在你的项目中, 你可以选择最合适的方法去查找元素。Selenium提供了下列的方法给你:
- find_element_by_id
- find_element_by_name
- find_element_by_xpath
- find_element_by_link_text
- find_element_by_partial_link_text
- find_element_by_tag_name
- find_element_by_class_name
- find_element_by_css_selector
一次查找多个元素 (这些方法会返回一个list列表):
- find_elements_by_name
- find_elements_by_xpath
- find_elements_by_link_text
- find_elements_by_partial_link_text
- find_elements_by_tag_name
- find_elements_by_class_name
- find_elements_by_css_selector
除了上述的公共方法,下面还有两个私有方法,在你查找也页面元素的时候也许有用。 他们是 find_element 和 find_elements 。
用法示例:
from selenium.webdriver.common.by import By
driver.find_element(By.XPATH, '//button[text()="Some text"]')
driver.find_elements(By.XPATH, '//button')
下面是 By 类的一些可用属性:
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"
5.2. 填写表单
5.2.1. 文本框处理
文本框中输入一些内容:
element.send_keys("some text")
你还可以通过”Keys”类来模式输入方向键:
element.send_keys(" and some", Keys.ARROW_DOWN)
对于任何元素,他可能都叫 send_keys ,这就使得它可以测试键盘快捷键, 比如当你使用Gmail的时候。但是有一个副作用是当你输入一些文本时,这些 输入框中原有的文本不会被自动清除掉,相反,你的输入会继续添加到已存在文本之后。 你可以很方便的使用 clear 方法去清除input或者textarea元素中的内容:
element.clear()
5.2.2. 选择框处理
WebDriver的支持类包括一个叫做Select的类,他提供有用的方法处理这些内容:
Select(element)
WebDriver 也提供一些有用的方法来取消选择已经选择的元素:
select = Select(driver.find_element_by_id('id'))
select.deselect_all()
获得所以选项:
options = select.options
5.2.3. 提交表单
有一个方法就是去找到一个“submit” 按钮然后点击它:
# Assume the button has the ID "submit" :)
driver.find_element_by_id("submit").click()
或者,WebDriver对每一个元素都有一个叫做 “submit” 的方法,如果你在一个表单内的 元素上使用该方法,WebDriver会在DOM树上就近找到最近的表单,返回提交它。 如果调用的元素不再表单内,将会抛出NoSuchElementException
异常:
element.submit()
5.3. 拖放
您可以使用拖放,无论是移动一个元素,或放到另一个元素内:
element = driver.find_element_by_name("source")
target = driver.find_element_by_name("target")
from selenium.webdriver import ActionChains
action_chains = ActionChains(driver)
action_chains.drag_and_drop(element, target).perform()
5.4.在窗口(window)和框架(frame)间移动
5.4.1.窗口间切换
方法一:**
现在的网页应用里没有页面框架或者只用一个窗口就包含了所有内容的已经很少了。WebDriver 支持在指定的窗口间移动,方法为switch_to_window
:
driver.switch_to_window("windowName")
现在所有的driver的调用都会指向这个给定的窗口,但是我们怎么知道窗口的名字是什么呢?可以看一看打开这个窗口的javascript
脚本或者link
链接:
<a href="somewhere.html" target="windowName">Click here to open a new window</a>
方法二:
传一个window handle
给switch_to_window()
方法,它就可以像这样迭代每一个打开的窗口:
for handle in driver.window_handles:
driver.switch_to_window(handle)
5.4.2.切换到框架
你也可以在框架和框架之间切换 (or into iframes):
driver.switch_to_frame("frameName")
我们可以用.
分离路径来访问子框架,并且可以指定它的索引:
driver.switch_to_frame("frameName.0.child")
这会跳到'frameName'框架内第一个名为'child'的子框架。All frames are evaluated as if from top.
一旦我们操作完了框架,我们可以通过下面的操作回到父框架:
driver.switch_to_default_content()
5.5.弹出对话框
Selenium内置支持处理弹出对话框,当你触发了弹框操作,你可以用下面的方法获得对话框元素:
alert = driver.switch_to_alert()
上述代码返回当前打开的对话框对象,有了这个对象 我们可以做确定、忽略、阅读提示文本或者甚至输入prompt,这个接口可以很好的操作alerts、confirms、prompts等对话框。更多内容参阅API文档
5.6.导航:历史记录和定位
前面我们可以使用get命令(driver.get("http://www.example.com")
)导航到一个页面。如你所见,WebDriver有一些较小的,侧重任务的接口,导航是一个很有用的任务,要打开一个页面,你可以使用get
方法:
driver.get("http://www.example.com")
要在浏览器的历史记录的后退或者前进:
driver.forward()
driver.back()
要记得这些函数完全依赖于底层驱动,如果你过去习惯某一个浏览器的运行状态,当切换到新的浏览器时,调用这些方法有可能会出现预料之外的情况。(原文:It’s just possible that something unexpected may happen when you call these methods if you’re used to the behaviour of one browser over another.)
5.7.Cookies
Before we leave these next steps。你可能会好奇如何使用cookie,首先你需要处在一个域名下,然后这样设置cookie:
# Go to the correct domain
driver.get("http://example.com")
# Now set the cookie. This one's valid for the entire domain
cookie = {'name':'foo','value':'bar'}
driver.add_cookie(cookie)
# And now output all the available cookies for the current URL
driver.get_cookies()
6.等待事件
现在很多Web应用都在使用AJAX技术。浏览器载入一个页面时,页面内的元素可能是在不同的时间载入的,这会加大定位元素的困难程度,因为元素不在DOM里,会抛出ElementNotVisibleException
异常,使用waits
,我们就可以解决这个问题。Waiting给(页面)动作的执行提供了一些时间间隔-通常是元素定位或者其他对元素的操作。
Selenium WebDriver提供了两类waits
- 隐式和显式。显式的waits
会让WebDriver在更深一步的执行前等待一个确定的条件触发,隐式的waits
则会让WebDriver试图定位元素的时候对DOM进行指定次数的轮询。
6.1.强制等待(无条件等待)
使用方法:time.sleep(delay)
delay的单位为秒,delay设置多少秒页面就会等待多少秒(死等),这个方法很容易让线程挂掉,使程序抛异常,所以要慎用此方法。
time.sleep(5)
6.2.显式等待(有条件等待)
当等待的条件满足后(一般用来判断需要等待的元素是否加载出来),就继续下一步操作。等不到就一直等,如果在规定的时间之内都没找到,那么就跳出Exception。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Firefox()
driver.get("http://somedomain/url_that_delays_loading")
try:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "myDynamicElement"))
)
finally:
driver.quit()
这段代码会等待10秒,如果10秒内找到元素则立即返回,否则会抛出TimeoutException
异常,WebDriverWait默认每500毫秒调用一下ExpectedCondition
直到它返回成功为止。ExpectedCondition
类型是布尔的,成功的返回值就是true,其他类型的ExpectedCondition
成功的返回值就是 not null
预期条件
自动化网页操作时,有许多频繁使用到的通用条件。下面列出的是每一个条件的实现。Selenium + Python 提供了许多方便的方法,因此你不需要自己编写expected_condition
的类,或者创建你自己的通用包。
- title_is
- title_contains
- presence_of_element_located
- visibility_of_element_located
- visibility_of
- presence_of_all_elements_located
- text_to_be_present_in_element
- text_to_be_present_in_element_value
- frame_to_be_available_and_switch_to_it
- invisibility_of_element_located
- element_to_be_clickable - 元素展示并且可用
- staleness_of
- element_to_be_selected
- element_located_to_be_selected
- element_selection_state_to_be
- element_located_selection_state_to_be
- alert_is_present
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver,10)
element = wait.until(EC.element_to_be_clickable((By.ID,'someid')))
expected_conditions
模块包含了一系列预定义的条件来和WebDriverWait使用
6.3.隐式等待(无条件等待,在一个时间段内等待)
当我们要找一个或者一些不能立即可用的元素的时候,隐式waits
会告诉WebDriver轮询DOM指定的次数,默认设置是0次。一旦设定,WebDriver对象实例的整个生命周期的隐式调用也就设定好了。
from selenium import webdriver
driver = webdriver.Firefox()
driver.implicitly_wait(10) # seconds
driver.get("http://somedomain/url_that_delays_loading")
myDynamicElement = driver.find_element_by_id('myDynamicElement')
以下根据stackoverflow网友回答添加:原问题链接 推荐一直用显式的,忘记还有隐式吧(Always use explicit wait. Forget that implicit wait exists)
显示waits: 明确的行为表现 在本地的selenium运行(你选择的编程语言) 可以在任何你能想到的条件下工作 返回成功或者超时 可以定义元素的缺失为条件 可以定制重试间隔,可以忽略某些异常
隐式waits: 不明确的行为表现,同一个问题依赖于不同的操作系统,不同的浏览器,不同的selenium版本会有各种不同的表现 在远程的selenium上运行(控制浏览器的那部分). 只能在寻找元素的函数上工作 返回找到元素或者(在超时以后)没有找到 如果检查元素缺失那么总是会等待到超时 除了时间啥都不能指定
如果是只需等待页面中的一个元素加载就用显示等待,等待整个网页加载就用隐式等待。
7.行为链
class selenium.webdriver.common.action_chains.ActionChains(driver)
ActionChains
可以完成简单的交互行为,例如鼠标移动,鼠标点击事件,键盘输入,以及内容菜单交互。这对于模拟那些复杂的类似于鼠标悬停和拖拽行为很有用
当你在ActionChains
对象上调用行为方法时,这些行为会存储在ActionChains
对象的一个队列里。调用perform()
时,这些动作就以他们队列的顺序来触发
ActionChains
可以使用链式模型:
menu = driver.find_element_by_css_selector(".nav")
hidden_submenu = driver.find_element_by_css_selector(".nav #submenu1")
ActionChains(driver).move_to_element(menu).click(hidden_submenu).perform()
或者也可以一个个排队,然后执行:
menu = driver.find_element_by_css_selector(".nav")
hidden_submenu = driver.find_element_by_css_selector(".nav #submenu1")
actions = ActionChains(driver)
actions.move_to_element(menu)
actions.click(hidden_submenu)
action.perform()
不管怎样,这些动作总是一个接一个按他们被调用的顺序执行。
-
click(on_element=None)
点击一个元素
参数: * on_element:要点击的元素,如果是
None
,点击鼠标当前的位置 -
click_and_hold(on_element=None)
鼠标左键点击一个元素并且保持
参数: * on_element:同click()类似
-
double_click(on_element=None)
双击一个元素
参数: * on_element:同click()类似
-
drag_and_drop(source, target)
鼠标左键点击
source
元素,然后移动到target
元素释放鼠标按键参数: source:鼠标点击的元素
target:鼠标松开的元素
-
drag_and_drop_by_offset(source, xoffset,yoffset)
拖拽目标元素到指定的偏移点释放
参数: source:点击的参数
xoffset:X偏移量
* yoffset:Y偏移量
-
key_down(value,element=None)
只按下键盘,不释放。我们应该只对那些功能键使用(Contril,Alt,Shift)
参数: value:要发送的键,值在
Keys
类里有定义 element:发送的目标元素,如果是None
,value会发到当前聚焦的元素上 -
key_up(value,element=None)
释放键。参考key_down的解释
-
move_by_offset(xoffset,yoffset)
将当前鼠标的位置进行移动
参数: xoffset:要移动的X偏移量,可以是正也可以是负
yoffset:要移动的Y偏移量,可以是正也可以是负
-
move_to_element(to_element)
把鼠标移到一个元素的中间
参数: *to_element:目标元素
-
move_to_element_with_offset(to_element,xoffset,yoffset)
鼠标移动到元素的指定位置,偏移量以元素的左上角为基准
参数: to_element:目标元素
xoffset:要移动的X偏移量
*yoffset:要移动的Y偏移量
-
perform()
执行所有存储的动作
-
release(on_element=None)
释放一个元素上的鼠标按键,
参数: * on_element:如果为
None
,在当前鼠标位置上释放 -
send_keys(*keys_to_send)
向当前的焦点元素发送键
参数: * keys_to_send:要发送的键,修饰键可以到
Keys
类里找到 -
send_keys_to_element(element,*keys_to_send)
向指定的元素发送键
8.警告框
class selenium.webdriver.common.alert.Alert(driver)
允许对警告框进行操作
使用这个类和警告提醒框进行交互,这个类包含了忽略、接受、输入以及从提示框内获取文本的方法
-
accept()
确认提示框,用法:
Alert(driver).accept() #Confirm a alert dialog
-
authenticate(username,password)
向一个认证的对话框发送用户名和密码,会自动点击确认:
driver.switch_to.alert.authenticate('cheese','secretGouda')
参数: username:username区域要填写的字符串 password:password区域要填写的字符串
-
dismiss()
忽略弹框
-
send_keys()
弹框中输入字符
name_prompt = Alert(driver) name_prompt.send_keys("Willian Shakephere") name_prompt.accept()
-
.text
读取弹框的提示字符
alert_text = Alert(driver).text self.assertEqual("Do you wish to quit?",alert_text)
9.特殊字符(Keys)
class selenium.webdriver.common.keys.Keys
下面是一些特殊字符的代码:
ADD = u'\ue025'
ALT = u'\ue00a'
ARROW_DOWN = u'\ue015'
ARROW_LEFT = u'\ue012'
ARROW_RIGHT = u'\ue014'
ARROW_UP = u'\ue013'
BACKSPACE = u'\ue003'
BACK_SPACE = u'\ue003'
CANCEL = u'\ue001'
CLEAR = u'\ue005'
COMMAND = u'\ue03d'
CONTROL = u'\ue009'
DECIMAL = u'\ue028'
DELETE = u'\ue017'
DIVIDE = u'\ue029'
DOWN = u'\ue015'
END = u'\ue010'
ENTER = u'\ue007'
EQUALS = u'\ue019'
ESCAPE = u'\ue00c'
F1 = u'\ue031'
F10 = u'\ue03a'
F11 = u'\ue03b'
F12 = u'\ue03c'
F2 = u'\ue032'
F3 = u'\ue033'
F4 = u'\ue034'
F5 = u'\ue035'
F6 = u'\ue036'
F7 = u'\ue037'
F8 = u'\ue038'
F9 = u'\ue039'
HELP = u'\ue002'
HOME = u'\ue011'
INSERT = u'\ue016'
LEFT = u'\ue012'
LEFT_ALT = u'\ue00a'
LEFT_CONTROL = u'\ue009'
LEFT_SHIFT = u'\ue008'
META = u'\ue03d'
MULTIPLY = u'\ue024'
NULL = u'\ue000'
NUMPAD0 = u'\ue01a'
NUMPAD1 = u'\ue01b'
NUMPAD2 = u'\ue01c'
NUMPAD3 = u'\ue01d'
NUMPAD4 = u'\ue01e'
NUMPAD5 = u'\ue01f'
NUMPAD6 = u'\ue020'
NUMPAD7 = u'\ue021'
NUMPAD8 = u'\ue022'
NUMPAD9 = u'\ue023'
PAGE_DOWN = u'\ue00f'
PAGE_UP = u'\ue00e'
PAUSE = u'\ue00b'
RETURN = u'\ue006'
RIGHT = u'\ue014'
SEMICOLON = u'\ue018'
SEPARATOR = u'\ue026'
SHIFT = u'\ue008'
SPACE = u'\ue00d'
SUBTRACT = u'\ue027'
TAB = u'\ue004'
UP = u'\ue013'
10.异常
所有的页面驱动代码里都可能抛出异常。
-
exception selenium.common.exceptions.ElementNotSelectableException(msg=None,screen=None,stacktrace=None)
基于
selenium.common.exceptions.InvalidElementStateException
当试图选中一个不能选中的元素时抛出 例如,选中一个
script
元素 -
exception selenium.common.exceptions.ElementNotVisibleException(msg=None,screen=None,stacktrace=None)
基于
selenium.common.exceptions.InvalidElementStateException
当DOM上存在元素但是不可用时,它是不可以进行交互的
最常见的场景是试图点击或者阅读一个隐藏的元素
-
exception selenium.common.exceptions.ErrorInResponseException(response,msg)
基于
selenium.common.exception.WebDriverException
服务端发生错误
这个异常可能会在 和 firefox扩展或者远程驱动服务交互时产生
-
exception selenium.common.exceptions.ImeActivationFailedException(msg=None,screen=None,stacktrace=None)
基于
selenium.common.exceptions.WebDriverException
激活一个 IME引擎失败
-
exception selenium.common.exceptions.ImeNotAvailableException(msg=None,screen=None,stacktrace=None)
基于
selenium.common.exceptions.WebDriverException
IME支持不可用。 如果 机器上IME支持不可用,这个异常会在所有和IME相关的方法里抛出
-
exception selenium.common.exceptions.InvalidCookieDomainException(msg=None, screen=None, stacktrace=None)
基于:
selenium.common.exceptions.WebDriverException
试图在一个和当前不同的域名下添加cookie
-
exception selenium.common.exceptions.InvalidElementStateException(msg=None, screen=None, stacktrace=None)
基于:
selenium.common.exceptions.WebDriverException
元素状态无效
-
exception selenium.common.exceptions.InvalidSelectorException(msg=None, screen=None, stacktrace=None)
基于:
selenium.common.exceptions.NoSuchElementException
选择器用来寻找元素,但返回的不是一个 WebElement时。 目前只会在XPath表达式选择器里产生,XPath表达式语法错误或者没有选择WebElement时(例:
count(//input)
) -
exception selenium.common.exceptions.InvalidSwitchToTargetException(msg=None, screen=None, stacktrace=None)
基于:
selenium.common.exceptions.WebDriverException
要切换的窗口或者框架不存在时
-
exception selenium.common.exceptions.MoveTargetOutOfBoundsException(msg=None, screen=None, stacktrace=None)
基于:
selenium.common.exceptions.WebDriverException
提供给
ActionsChains
move()方法的目标不可用。 -
exception selenium.common.exceptions.NoAlertPresentException(msg=None, screen=None, stacktrace=None)
基于:
selenium.common.exceptions.WebDriverException
屏幕没有警告框时,切换到警告框
-
exception selenium.common.exceptions.NoSuchAttributeException(msg=None, screen=None, stacktrace=None)
基于:
selenium.common.exceptions.WebDriverException
元素找不到这个属性。
你可能会想在另外一个浏览器上检查某个属性是否存在,有些浏览器相同的属性有不同的属性名(IE8的 innerText和 Firefox的 textContent)
-
exception selenium.common.exceptions.NoSuchElementException(msg=None, screen=None, stacktrace=None)
基于:
selenium.common.exceptions.WebDriverException
找不到元素
如果你发现这个错误,你可能会想要检查下面的东西: 检查你
find_by...
函数里用的选择器 查找元素的时候页面上还没有这个元素(页面正在加载)请查阅
selenium.webdriver.support.wait.WebDriverWait()
来了解如何等待元素的出现 -
exception selenium.common.exceptions.NoSuchFrameException(msg=None, screen=None, stacktrace=None)
基于:
selenium.common.exceptions.InvalidSwitchToTargetException
要切换的目标框架不存在
-
exception selenium.common.exceptions.NoSuchWindowException(msg=None, screen=None, stacktrace=None)
基于:
selenium.common.exceptions.InvalidSwitchToTargetException
要切换的目标窗口不存在。
要找到当前活动窗口的句柄,你可以用下面的方法来获取一个句柄列表:
print(driver.window_handles)
-
exception selenium.common.exceptions.RemoteDriverServerException(msg=None, screen=None, stacktrace=None)
基于:
selenium.common.exceptions.WebDriverException
当一个元素的引用
变旧
变旧的意思是这个元素不在出现在页面的DOM里
可能出现这个异常的原因包括但不限于: 你不在同一个页面,或者你获取到元素之后页面被刷新了 元素被定位后 被移动了又重新加到屏幕上,这样元素就被重置了。典型的例子是javascript框架当值改变,节点就被重建了 *,元素所在的框架或者其他内容被刷新了
-
exception selenium.common.exceptions.TimeoutException(msg=None, screen=None, stacktrace=None)
基于:
selenium.common.exceptions.WebDriverException
规定时间内一个命令没有执行完
-
exception selenium.common.exceptions.UnableToSetCookieException(msg=None, screen=None, stacktrace=None)
基于:
selenium.common.exceptions.WebDriverException
驱动设置cookie失败
-
exception selenium.common.exceptions.UnexpectedAlertPresentException(msg=None, screen=None, stacktrace=None)
基于:
selenium.common.exceptions.WebDriverException
预料之外的警告框。当一个警告框阻塞了webdriver,不能执行任何命令的时候。
-
exception selenium.common.exceptions.UnexpectedTagNameException(msg=None, screen=None, stacktrace=None)
基于:
selenium.common.exceptions.WebDriverException
当一个支持的类没有拿到预料的web元素时
-
exception selenium.common.exceptions.WebDriverException(msg=None, screen=None, stacktrace=None)
基于:
exceptions.Exception
基本的 webdriver 异常
11.页面对象
这章是对 页面对象设计模型的特别指导。一个页面对象代表了你要测试的用户接口交互的区域。
使用页面对象模型的好处: 可以写出能在多个测试案例里复用的代码 减少重复代码 * 如果用户接口更改,只需要在一个地方做相应修改即可
测试案例
下面这个测试案例测试了在python.org
网页上搜索一个单词并确认有相应的搜索结果:
import unittest
from selenium import webdriver
import page
class PythonOrgSearch(unittest.TestCase):
"""一个简单展示页面对象如何工作的类"""
def setUp(self):
self.driver = webdriver.Firefox()
self.driver.get("http://www.python.org")
def test_search_in_python_org(self):
"""
测试 python.org网站的搜索功能。搜索一个单词“pycon”然后验证某些结果会展示出来。
注意这个测试不会在搜索结果页里寻找任何细节文本,它只会验证结果为非空
"""
#载入主页面,这个例子里是 Python.org的首页
main_page = page.MainPage(self.driver)
#检查页面的标题是否包含"python"单词
assert main_page.is_title_matches(), "python.org title doesn't match."
#将搜索框的文本设置为"pycon"
main_page.search_text_element = "pycon"
main_page.click_go_button()
search_results_page = page.SearchResultsPage(self.driver)
#验证结果页非空
assert search_results_page.is_results_found(), "No results found."
def tearDown(self):
self.driver.close()
if __name__ == "__main__":
unittest.main()
页面对象类
页面对象模型旨在给每一个Web页面创造一个对象。运用这个技术我们可以在测试代码和技术实现之间创建一个分离层,page.py
会是这样的:
from element import BasePageElement
from locators import MainPageLocators
class SearchTextElement(BasePageElement):
"""这个类从指定的定位器里获取到搜索文本"""
#已经输入搜索字符串的搜索框的定位器
locator = 'q'
class BasePage(object):
"""初始化所有页面都会调用的基本页类"""
def __init__(self, driver):
self.driver = driver
class MainPage(BasePage):
"""主页操作方法放这里"""
#定义一个变量存放检索文本
search_text_element = SearchTextElement()
def is_title_matches(self):
"""验证硬编码字符"python"出现在页面标题里"""
return "Python" in self.driver.title
def click_go_button(self):
"""触发搜索功能"""
element = self.driver.find_element(*MainPageLocators.GO_BUTTON)
element.click()
class SearchResultsPage(BasePage):
"""搜索结果页操作方法放这里"""
def is_results_found(self):
# 或许应该在具体的页面元素里搜索文本,不过目前为止这样运行没什么问题
return "No results found." not in self.driver.page_source
页面元素
element.py
类大致是这样的:
from selenium.webdriver.support.ui import WebDriverWait
class BasePageElement(object):
"""初始化每个页面对象类的基本页类"""
def __set__(self, obj, value):
"""用给定的值设置文本"""
driver = obj.driver
WebDriverWait(driver, 100).until(
lambda driver: driver.find_element_by_name(self.locator))
driver.find_element_by_name(self.locator).send_keys(value)
def __get__(self, obj, owner):
"""从具体的对象里获取文本"""
driver = obj.driver
WebDriverWait(driver, 100).until(
lambda driver: driver.find_element_by_name(self.locator))
element = driver.find_element_by_name(self.locator)
return element.get_attribute("value")
定位器
One of the practices is to separate the locator strings from the place where they are being used.在这个例子里,同页面的定位器是同一个类
The locators.py will look like this:
from selenium.webdriver.common.by import By
class MainPageLocators(object):
"""一个主页面定位器类,所有的页面定位器应该来自这里"""
GO_BUTTON = (By.ID, 'submit')
class SearchResultsPageLocators(object):
"""一个搜索结果定位器类,所有搜索结果定位器应该来自这里"""
pass
12.其他
12.1.怎么滚动到页面的底部?
相关链接:http://blog.varunin.com/2011/08/scrolling-on-pages-using-selenium.html
你可以使用execute_script
方法来在载入的页面上执行JS,因此,你可以调用JS的API来滚动到页面的底部或者其他任意位置。
下面是一个滚动到底部的实例:
driver.execute_script("window.scrollTo(0,document.body.scrollHeight);")
DOM的窗口对象有一个 scrollTo 方法来在打开的窗口中滚动到任意位置, scrollHeight是所有元素的一个通用属性,document.body.scrollHeight
是页面整个body
的高度
12.2.怎么向文件上传表单上传文件?
选中元素,调用send_keys()
方法,传递文件的路径。可以传递绝对路径或者相对测试脚本的路径。要注意windows和Unix系统路径名的差异
12.3.怎样给当前窗口截图?
使用webdriver提供的save_screenshot
方法:
from selenium import webdriver
driver = webdriver.Firefox()
driver.get('http://www.python.org/')
driver.save_screenshot('screenshot.png')
driver.quit()
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧