目录
一 Webdriver介绍
二 webdriver实现的原理
三 API介绍
Webdriver 元素的查找的八种方式
find_element_by_id() 源码
find_element_by_name() 源码
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()
find_elements_by_xpath()
execute_script() # JS操作
复数形式的8中元素查找
四 浏览器的基本操作
driver.get() #打开地址
driver.title 获取title
current_url 获取当前页面的URL
page_source # 返回页面的源码
driver.refresh() #刷新
driver.forward() # 前进
driver.back() # 后退
driver.maximize_window() # 最大化浏览器
driver.minimize_window() #最小化浏览器
五 窗口操作
current_window_handle() #获得当前窗口的句柄
window_handles() #获得当前所有打开的窗口的句柄
switch_to_window #切换窗口
fullscreen_window # 全屏浏览器
set_window_size #设置窗口的大小
get_window_size #获得当前窗口的高度和大小
set_window_position # 设置窗口的坐标
get_window_position # 获得当前窗口的坐标
get_window_rect
set_window_rect
六 关闭浏览器
driver.close()
driver.quit()
七 切换
switch_to
switch_to_active_element # 返回当前的焦点对象
switch_to_window # 切换窗口
switch_to_frame
switch_to_default_content # 嵌套frame操作
switch_to_alert
switch_to_alert 和switch_to_window的区别?
alert的操作
八 浏览器Cookie操作
绕过登录的验证码
九 等待时间
implicitly_wait() # 隐式等待
selenium的显示等待
元素出现:until()
元素消失: until_not()
driver.set_script_timeout()
driver.set_page_load_timeout()
desired_capabilities
十 截图
driver.get_screenshot_as_file("D:\\Test\\1.png") # 截图,并设置保存路径
driver.save_screenshot() #保存截图
driver.get_screenshot_as_png() #截图,保存为二进制数据
driver.get_screenshot_as_base64() #截图,保存为base64格式
十一 日志
driver.get_log()
driver.log_types
通过向远程服务器发送命令来控制浏览器。
该服务器应该运行WebDriver有线协议
属性:
- session_id - 此WebDriver启动和控制的浏览器会话的字符串ID。
- 功能 - 返回此浏览器会话的有效功能
- command_executor - 用于执行命令的remote_connection.RemoteConnection对象。
- error_handler - 用于处理错误的errorhandler.ErrorHandler对象。
创建一个使用有线协议发出命令的新驱动程序。
:参数数量:
- command_executor - 表示远程服务器的URL或自定义的字符串
remote_connection.RemoteConnection对象。默认为“http://127.0.0.1:4444/wd/hub”。
- desired_capabilities - 请求何时的功能字典
启动浏览器会话。必需参数。
- browser_profile - selenium.webdriver.firefox.firefox_profile.FirefoxProfile对象。
仅在请求Firefox时使用。可选的。
- proxy - 一个selenium.webdriver.common.proxy.Proxy对象。浏览器会话将
如果可能,请使用给定的代理设置启动。可选的。
- keep_alive - 是否配置要使用的remote_connection.RemoteConnection
HTTP保持活跃。默认为False。
- file_detector - 在实例化期间传递自定义文件检测器对象。如果没有,
然后将使用默认的LocalFileDetector()。
- options - 驱动程序options.Options类的实例
关于实现的原理,可以看下这个博主的总结:
webdriver实现原理
WebDriver 是按照 server – client 的经典设计模式设计的。
server 端就是 remote server,可以是任意的浏览器。当我们的脚本启动浏览器后,该浏览器就是 remote server,它的职责就是等待 client 发送请求并做出相应。client 端简单说来就是我们的测试代码,我们测试代码中的一些行为,比如打开浏览器,转跳到特定的 url 等操作是以 http 请求的方式发送给被 测试浏览器,也就是 remote server;remote server 接受请求,并执行相应操作,并在 response 中返回执行状态、返回值等信息。
webdriver 的工作流程:
1. WebDriver 启动目标浏览器,并绑定到指定端口。该启动的浏览器实例,做为 WebDriver 的 remote
server。
2. Client 端通过 CommandExcuter 发送 HTTPRequest 给 remote server 的侦听端口(通信协议: the
webriver wire protocol)
3. Remote server 需要依赖原生的浏览器组件(如:IEDriverServer.exe、chromedriver.exe),来转化转
化浏览器的 native 调用
webdriver 利用的是驱动来操作浏览器中的页面元素。 具体的过程是这样的,利用各种驱动(谷歌的 chromedriver 等)来控制浏览器 ,这里也就是为什么我们每次新建一个 webdriver 对象时,需要这样定义。driver=webdriver.Chrome() 不同的浏览器需要使用不同的方法,驱动也不一样。然后操作浏览器时使用的是与浏览器之间的通信协议 The WebDriver Wire Protocol 。
每次都使用 json 来传输数据。客户端发送一个 requset,服务器端返回一个 response。代码控制驱动器然后驱动去控制浏览器 然后浏览器完成我们代码的需要的操作。
每次都需要借助一个 ComandExecutor 发送一个命令,实际上是一个 HTTP request 给监听端口上的 Web Service。在我们的 HTTP request 的 body 中,会以 WebDriver Wire 协议规定的 JSON 格式的字符串来告诉浏览器怎么做。
详细的API介绍,这个从网上找的别人写好的总结,非常棒。
例子
driver.find_element_by_id("kw")
例子:
find_element_by_name("wd")
例子:
地图
find_element_by_link_text("地图")
parial link 定位是对 link 定们的一个种补充,有些文本连接会比较长,这个时候我们可以取文本链接的有一部分定位,只要这一部分信息可以唯一的标识这个链接。
例子:
链接非常的长长长哒哒哒哒哒哒多点对点
find_element_by_partial_link_text("链接非常的长")
Args: tag定位取的是一个HTML页面的 tag(标签) 比如:h1, a, span
缺点:元素很多都是相同的tag,定位会不准确,不推荐使用
CSS语法:
例子:
find_element_by_css_selector(".s_ipt")
find_element_by_css_selector("#kw")
例子:
find_element_by_xpath("//input[@id='kw']")
js="return $('#nv a')"
link = driver.execute_script(js)
例子:
from selenium import webdriver
driver = webdriver.FireFox()
driver.get("http://www.baidu.com")
例子:
import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("http://www.baidu.com/")
time.sleep(1)
driver.find_element_by_link_text("新闻").click()
time.sleep(1)
print (driver.title) # title方法可以获取当前页面的标题显示的字段
import time
from selenium import webdriver
driver = webdriver.FireFox()
drive.get("https://www.baidu.com")
driver.find_element_by_link_text("新闻").click()
current_url = driver.current_url # 获取当前页面的url
print(current_url)
driver.quit()
用途:当你8大元素定位都定位不到时候,你可以用这个试试,获取到页面信息,用正则提取出我们想要的东西
例子:
from selenium import webdriver
driver = webdriver.FireFox()
driver.get("https://blog.csdn.net/ricky_yangrui")
page = driver.page_source
print(page)
from selenium import webdriver
import time
driver = webdriver.FireFox()
driver.get("http://www.baidu.com")
time.sleep(3)
driver.refresh()
from selenium import webdriver
import time
driver = webdriver.FireFox()
driver.get("https://www.baidu.com")
time.sleep(2)
driver.get("https://www.hao123.com")
time.sleep(2)
# 返回到上一页
driver.back()
time.sleep(3)
# 切换到下一页
driver.forward()
import time
from selenium import webdriver
import re
driver = webdriver.Firefox()
driver.get("https://www.baidu.com")
time.sleep(2)
driver.minimize_window()
例子:
#coding=utf-8
from selenium import webdriver
driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get("http://www.baidu.com")
#获得百度搜索窗口句柄
sreach_windows= driver.current_window_handle
driver.find_element_by_link_text(u'登录').click()
driver.find_element_by_link_text(u"立即注册").click()
#获得当前所有打开的窗口的句柄
all_handles = driver.window_handles
#进入注册窗口
for handle in all_handles:
if handle != sreach_windows:
driver.switch_to_window(handle)
print 'now register window!'
driver.find_element_by_name("account").send_keys('username')
driver.find_element_by_name('password').send_keys('password')
#……
#进入搜索窗口
for handle in all_handles:
if handle == sreach_windows:
driver.switch_to_window(handle)
print 'now sreach window!'
driver.find_element_by_id('TANGRAM__PSP_2__closeBtn').click()
driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()
time.sleep(5)
driver.quit()
例子:
import time
from selenium import webdriver
import re
driver = webdriver.Firefox()
driver.get("https://www.baidu.com")
time.sleep(2)
# 全屏
driver.fullscreen_window()
# 设置窗口大小500 * 234
driver.set_window_size(500, 234)
例子:
例子:
例子:
例子: 见源码上的 Usage
Note: 有时候写driver.close() 会报错
sys.meta_path is None, Python is likely shutting down,这个我们看源代码就发现了,close只是关闭其中一个窗口,并没有关闭进程,看quit() ,就发现了,他是关闭了进程的 self.stop_client() ,遇到这个报错的时候,我们可以使用driver.quit() 试试。
我们看源码上的例子:
element = driver.switch_to.active_element alert = driver.switch_to.alert driver.switch_to.default_content() driver.switch_to.frame('frame_name') driver.switch_to.frame(1) driver.switch_to.frame(driver.find_elements_by_tag_name("iframe")[0]) driver.switch_to.parent_frame() driver.switch_to.window('main')
alert ——返回浏览器的Alert对象,可对浏览器alert、confirm、prompt框操作 default_content() ——切到主文档 frame(frame_reference) ——切到某个frame parent_frame() ——切到父frame,这个方法也不常被人所知,但有多层frame的时候很有用 window(window_name) ——切到某个浏览器窗口 active_element ——返回当前焦点的WebElement对象
焦点就是我们操作网页的时候,光标的位置;
例子:我们常用的就是新建文件夹的时候,点击了右键,新建,我们的光标就会到新建的文件夹上,这个时候我们要输入名字,光标是在文件夹里面闪动的,这个时候我们就可以用 switch_to_active_element 去输入名字,完成新建文件夹的操作;
l = driver.find_element_by_id('pm_treeRoom_1_span')
ActionChains(driver).context_click(l).perform()
driver.find_element_by_class_name('fnew').click()
time.sleep(2)
driver.switch_to.active_element.send_keys('filename')
time.sleep(2)
这个前面说过了。
这个方法假如被划了横线,那我们用 switch_to.frame
frame标签有frameset、frame、iframe三种,frameset跟其他普通标签没有区别,不会影响到正常的定位,而frame与iframe对selenium定位而言是一样的,selenium有一组方法对frame进行操作