本文目录
- Selenium和PhantomJS 终极最全使用总结
- Selenium截图的四种方法
- Selenium-针对alert弹窗无法获取,弹出no such alert的解决方法
- selenium之webdriver详解——小白进阶之路(二)
- Selenium webdriver有没有Verify值的方法
Selenium和PhantomJS 终极最全使用总结
PhantomJS 和 Chromedriver操作方式以及功能一致 主要区别 PhantomJS 无界面模式 节省内存 Chromedriver 完全模仿浏览器 消耗内存
PhantomJS 截取的是网页的完整页面,包括下拉进度条的内容 Chromedriver只截取弹框浏览器的可视化内容页面
001 先找到文本输入框元素,输入内容 002 找到搜索按钮 进行搜索
给输入框赋值: element.send_keys() 操作点击事件: element.click()
find_element和find_elements的区别 带s的返回的是列表 不带s的是返回列表中的第一个元素
selenium处理cookie
***隐藏网址*** 01 强制等待 time.sleep(10) 强制要求在时间内出现,否则报错,不能很好的控制时间,浪费资源
02 隐示等待 隐性等待对整个driver的周期都起作用,所以只要设置一次即可 隐形等待是设置了一个最长等待时间,如果在规定时间内网页加载完成,则执行下一步,否则一直等到时间截止,然后执行下一步。 driver.implicitly_wait(30) # 隐性等待,最长等30秒
03 显示等待
这里需要特别注意的是until或until_not中的可执行方法method参数,很多人传入了WebElement对象,如下:
这是错误的用法,这里的参数一定要是可以调用的,即这个对象一定有 call () 方法,否则会抛出异常: TypeError: ’xxx’ object is not callable
switch方法切换的操作 01窗口切换
iframe是html中常用的一种技术,即一个页面中嵌套了另一个网页,selenium默认是访问不了frame中的内容的,对应的解决思路是
思路:先定位并切换至iframe内,再进行你安排前元素操作 最后可通过切换至窗口,从iframe中切换出iframe 进入到页面
当你触发了某个事件之后,页面出现了弹窗提示,处理这个提示或者获取提示信息方法:driver.switch_to.alert() # 跟frame一样的处理方式!
页面前进和后退
selenium 三大重要功能
三个可以同时使用
selenium的优缺点 • selenium能够执行页面上的js,对于js渲染的数据和模拟登陆处理起来非常容易 • selenium由于在获取页面的过程中会发送很多请求,所以效率非常低,所以在很多时候需要酌情使用
Selenium截图的四种方法
Selenium网页截图的四种方法: 1. driver.get_screenshot_as_base64(): 用途:获取截屏的base64编码数据,在HTML界面输出截图时使用。 用法: 2. driver.get_screenshot_as_png(): 用途:获取获取二进制数据流 用法: 3. driver.save_screenshot(filename/full_path): 用途:获取截屏png图片,参数是文件名称,截屏必须是.png图片, 如果只给文件名,截图会保存在项目的根目录下面。 用法: 4. driver.get_screenshot_as_file(filename/full_path) 用途:获取截屏png图片,参数是文件的绝对路径,截屏必须是.png图片。如果只给文件名,截屏会存在项目的根目录下。 用法:
Selenium-针对alert弹窗无法获取,弹出no such alert的解决方法
在爬取网页的过程中,经常会遇到一些弹窗的情况,有alert、confirm、prompt等三种,区别如下:
提示消息框 提供了一个文本字段,用户可以在此字段输入一个答案来响应您的提示。该消息框有一个“确定”按钮和一个“取消”按钮。如果您提供了一个辅助字符串参数,则提示消息框将在文本字段显示该辅助字符串作为默认响应。否则,默认文本为 "《undefined》"。
这三种弹窗的共同点是,弹出之后你是获取不到任何网页内容的,也就是无法通过常规的driver.find_element_by_xpath这种形式来获取元素。F12是没有任何内容,也无法点选的。
selenium另外有一套方法来把driver转换到弹窗上:
其中driver就是你设置好的浏览器句柄,switch_to.alert代表你当前的弹窗类型,alert就对应alert,accept的意思就是点确定,另外还有dismiss等用法,网上很多了,不详细说。
用这个语句,就可以把弹窗点掉,之后正常操作,但是我重点想说的是以下内容:
在实际网页中,往往弹窗会有一定延时,这时候你用这个语句就会报一个no such alert的错误,意味着获取不到弹窗,此时要用如下的办法解决:
引用Webdriver类,里面的参数第一个是句柄,第二个则是超时等待时间,这里是10秒钟。
Webdriver这种方法叫做 显示等待 ,用一个默认频率不停的刷新(默认是0.5s),检测当前页面元素是否存在,如果超过10秒则抛出TimeOut。
很显然,这种方法比一般的sleep效率要高。 wait.until(EC.alert_is_present())就是判断弹窗是否存在,如果存在,那么就不会抛出异常,继续走下一步也就是获取到弹窗点击确定。
之后就可以进行正常的操作了。
selenium之webdriver详解——小白进阶之路(二)
笔记: 01.设置元素等待时间 自动化测试的时候,元素定位没有错,但是跑脚本的时候却报错了 例如,登录的时候要等登录页面加载出来才能输入用户名和密码 selenium设置元素等待时间的3种方式及区别 1.sleep() --固定等待时间:强制等待,不能把握准确的等等时间,适合调试时用 2.implicitly_wait() --隐式等待时间:等页面加载完成才执行下一步操作,一般设置一次即可 3.WebDriverWait --显示等待时间:配合untill()和not untill()方法,根据判断条件 灵活处理等待时间 要先设置一个超长时间,在这个时间内,程序根据调用频率每隔几秒查看一下,如果条件满足,则执行下一步操作,若不满足且超过了等待时间则抛出异常 导包:from selenium.webdriver.support.ui import WebDriverWait 使用:WebDriverWait(driver, 超时时间, 调用频率, 要忽略的异常).until(要执行的方法, 超时时返回的错误信息) 实例:replace:02.键盘事件Keys类 制表符:send_keys(Keys.TAB) 退出键:send_keys(Keys.ESCAPE) F1:send_keys(Keys.F1) f1~f12 以此类推03.二次定位 顾名思义,通过多个元素,定位两次 dr.find_element(By.CLASS_NAME,"s_input").send_keys("python") 二次定位: dr.find_element(By.NAME,"query").find_element(By.CLASS_NAME,"s_input").send_keys("python")04.selenium鼠标悬停类-- ActionChains() 导包:from selenium.webdriver.common.action_chainsimport ActionChains实例:将鼠标移动至更多设置,悬停鼠标elem1= dr.find_element(By.LINK_TEXT,"设置") ActionChains(dr).move_to_element(elem1).perform()05.selenium警告框的处理 很多web应用经常会遇到JavaScript编写的alert 、confirm 以及prompt 弹窗,需要用到switch_to.alert来切换弹窗,并对弹窗进行输入信息,关闭等处理。 switch_to.alert.text --获取弹窗文本信息 switch_to.alert.accept() --点击弹窗中确定按钮 switch_to.alert.dismiss() --点击弹出中取消按钮 switch_to.alert.sendKeys("字符串") --在弹窗中输入信息 实例:06.下拉菜单选择的三种方式导包:from selenium.webdriver.support.uiimport Select #选择下拉框的o2 elem1 = dr.find_element(By.ID,"s3Id") 1:根据value值定位 Select(elem1).select_by_value("o2val") 2.根据index定位 Select(elem1).select_by_index(1) 3.根据下拉框文本信息定位 Select(elem1).select_by_visible_text("o2")07.多窗口切换 window_handles --获取所有窗口句柄 switch_to.window(指定窗口) --切换到指定窗口08.selenium之JS操作浏览器滚动条位置 execute_script("window.scrollTo(0,n);")09.selenium之JS操作隐藏元素隐藏元素的标识:style="display:none;" 一般我们通过将隐藏元素的属性修改成显示再定位10.操作excel文件 将测试数据参数化用到 10.1准备参数化数据文件10.2导包 打开文件,填写文档路径运行结果: 定位到sheet的位置 读取sheet的行和列的内容 #读取表的行的方法 rows = sheet1.nrows print("行数",rows) columns = sheet1.ncols print("列数",columns)读取指定行的值 #读取指定行的值 rowValue1 = sheet1.row_values(0) print(rowValue1) #读取指定列的值 colValue1 = sheet1.col_values(0) print(colValue1)#输出所有用户名和对应的密码 for iin range(1,rows): print("用户名:" + sheet1.row_values(i))
Selenium webdriver有没有Verify值的方法
在使用selenium webdriver进行元素定位时,通常使用findElement或findElements方法结合By类返回的元素句柄来定位元素。其中By类的常用定位方式共八种,现分别介绍如下。 1. By.name() 假设我们要测试的页面源码如下: 《button id="gbqfba" aria-label="Google Search" name="btnK" class="gbqfba"》《span id="gbqfsa"》Google Search《/span》《/button》 当我们要用name属性来引用这个button并点击它时,代码如下: View Code 2. By.id() 页面源码如下: 1 《button id="gbqfba" aria-label="Google Search" name="btnK" class="gbqfba"》《span id="gbqfsa"》Google Search《/span》《/button》 要引用该button并点击它时,代码如下: 复制代码 1 public class SearchButtonById { 2 3 public static void main(String args){ 4 5 WebDriver driver = new FirefoxDriver(); 6***隐藏网址*** 8 9 WebElement searchBox = driver.findElement(By.id("gbqfba")); 10 11 searchBox.click(); 12 13 } 14 15 } 复制代码 3. By.tagName() 该方法可以通过元素的标签名称来查找元素。该方法跟之前两个方法的区别是,这个方法搜索到的元素通常不止一个,所以一般建议结合使用findElements方法来使用。比如我们现在要查找页面上有多少个button,就可以用button这个tagName来进行查找,代码如下: 复制代码 public class SearchPageByTagName{ public static void main(String args){ WebDriver driver = new FirefoxDriver();***隐藏网址*** List《WebElement》 buttons = driver.findElements(By.tagName("button")); System.out.println(buttons.size()); //打印出button的个数 } } 复制代码 另外,在使用tagName方法进行定位时,还有一个地方需要注意的是,通常有些HTML元素的tagName是相同的,如下图(1)所示。 图(1) 从图中我们可以看到,单选框、复选框、文本框和密码框的元素标签都是input,此时单靠tagName无法准确地得到我们想要的元素,需要结合type属性才能过滤出我们要的元素。示例代码如下: 复制代码 1 public class SearchElementsByTagName{ 2 3 public static void main(String args){ 4 5 WebDriver driver = new FirefoxDriver(); 6***隐藏网址*** 8 9 List《WebElement》 allInputs = driver.findElements(By.tagName("input")); 10 11 //只打印所有文本框的值 12 13 for(WebElement e: allInputs){ 14 15 if (e.getAttribute(“type”).equals(“text”)){ 16 17 System.out.println(e.getText().toString()); //打印出每个文本框里的值 18 19 } 20 21 } 22 23 } 24 25 } 复制代码 4. By.className() className属性是利用元素的css样式表所引用的伪类名称来进行元素查找的方法。对于任何HTML页面的元素来说,一般程序员或页面设计师会给元素直接赋予一个样式属性或者利用css文件里的伪类来定义元素样式,使元素在页面上显示时能够更加美观。一般css样式表可能会长成下面这个样子: 复制代码 1 .buttonStyle{ 2 3 width: 50px; 4 5 height: 50px; 6 7 border-radius: 50%; 8 9 margin: 0% 2%; 10 11 } 复制代码 定义好后,就可以在页面元素中引用上述定义好的样式,如下: 1 《button name="sampleBtnName" id="sampleBtnId" class="buttonStyle"》I’m Button《/button》 如果此时我们要通过className属性来查找该button并操作它的话,就可以使用className属性了,代码如下: 复制代码 1 public class SearchElementsByClassName{ 2 3 public static void main(String args){ 4 5 WebDriver driver = new FirefoxDriver(); 6***隐藏网址*** 8 9 WebElement searchBox = driver.findElement(By.className("buttonStyle")); 10 11 searchBox.sendKeys("Hello, world"); 12 13 } 14 15 } 复制代码 注意:使用className来进行元素定位时,有时会碰到一个元素指定了若干个class属性值的“复合样式”的情况,如下面这个button:《button id="J_sidebar_login" class="btn btn_big btn_submit" type="submit"》登录《/button》。这个button元素指定了三个不同的css伪类名作为它的样式属性值,此时就必须结合后面要介绍的cssSelector方法来定位了,稍后会有详细例子。 5. By.linkText() 这个方法比较直接,即通过超文本链接上的文字信息来定位元素,这种方式一般专门用于定位页面上的超文本链接。通常一个超文本链接会长成这个样子: 1 《a href="/intl/en/about.html"》About Google《/a》 我们定位这个元素时,可以使用下面的代码进行操作: 复制代码 1 public class SearchElementsByLinkText{ 2 3 public static void main(String args){ 4 5 WebDriver driver = new FirefoxDriver(); 6***隐藏网址*** 8 9 WebElement aboutLink = driver.findElement(By.linkText("About Google")); 10 11 aboutLink.click(); 12 13 } 14 15 } 复制代码 6. By.partialLinkText() 这个方法是上一个方法的扩展。当你不能准确知道超链接上的文本信息或者只想通过一些关键字进行匹配时,可以使用这个方法来通过部分链接文字进行匹配。代码如下: 复制代码 1 public class SearchElementsByPartialLinkText{ 2 3 public static void main(String args){ 4 5 WebDriver driver = new FirefoxDriver(); 6***隐藏网址*** 8 9 WebElement aboutLink = driver.findElement(By.partialLinkText("About")); 10 11 aboutLink.click(); 12 13 } 14 15 } 复制代码 注意:使用这种方法进行定位时,可能会引起的问题是,当你的页面中不止一个超链接包含About时,findElement方法只会返回第一个查找到的元素,而不会返回所有符合条件的元素。如果你要想获得所有符合条件的元素,还是只能使用findElements方法。 7. By.xpath() 这个方法是非常强大的元素查找方式,使用这种方法几乎可以定位到页面上的任意元素。在正式开始使用XPath进行定位前,我们先了解下什么是XPath。XPath是XML Path的简称,由于HTML文档本身就是一个标准的XML页面,所以我们可以使用XPath的语法来定位页面元素。 假设我们现在以图(2)所示HTML代码为例,要引用对应的对象,XPath语法如下: 图(2) 绝对路径写法(只有一种),写法如下: 引用页面上的form元素(即源码中的第3行):/html/body/form 注意:1. 元素的xpath绝对路径可通过firebug直接查询。2. 一般不推荐使用绝对路径的写法,因为一旦页面结构发生变化,该路径也随之失效,必须重新写。3. 绝对路径以单/号表示,而下面要讲的相对路径则以//表示,这个区别非常重要。另外需要多说一句的是,当xpath的路径以/开头时,表示让Xpath解析引擎从文档的根节点开始解析。当xpath路径以//开头时,则表示让xpath引擎从文档的任意符合的元素节点开始进行解析。而当/出现在xpath路径中时,则表示寻找父节点的直接子节点,当//出现在xpath路径中时,表示寻找父节点下任意符合条件的子节点,不管嵌套了多少层级(这些下面都有例子,大家可以参照来试验)。弄清这个原则,就可以理解其实xpath的路径可以绝对路径和相对路径混合在一起来进行表示,想怎么玩就怎么玩。 下面是相对路径的引用写法: 查找页面根元素:// 查找页面上所有的input元素://input 查找页面上第一个form元素内的直接子input元素(即只包括form元素的下一级input元素,使用绝对路径表示,单/号)://form/input 查找页面上第一个form元素内的所有子input元素(只要在form元素内的input都算,不管还嵌套了多少个其他标签,使用相对路径表示,双//号)://form//input 查找页面上第一个form元素://form 查找页面上id为loginForm的form元素://form 查找页面上具有name属性为username的input元素://input 查找页面上id为loginForm的form元素下的第一个input元素://form 查找页面具有name属性为contiune并且type属性为button的input元素://input 查找页面上id为loginForm的form元素下第4个input元素://form Xpath功能很强大,所以也可以写得更加复杂一些,如下面图(3)的HTML源码。 图(3) 如果我们现在要引用id为“J_password”的input元素,该怎么写呢?我们可以像下面这样写: WebElement password = driver.findElement(By.xpath("//*")); 也可以写成: WebElement password = driver.findElement(By.xpath("//*")); 这里解释一下,其中//*,这样肯定会报错的。 前面讲的都是xpath中基于准确元素属性的定位,其实xpath作为定位神器也可以用于模糊匹配。比如下面图(4)所示代码: 图(4) 这段代码中的“退出”这个超链接,没有标准id元素,只有一个rel和href,不是很好定位。不妨我们就用xpath的几种模糊匹配模式来定位它吧,主要有三种方式,举例如下。 a. 用contains关键字,定位代码如下: 1 driver.findElement(By.xpath(“//a”)); 这句话的意思是寻找页面中href属性值包含有logout这个单词的所有a元素,由于这个退出按钮的href属性里肯定会包含logout,所以这种方式是可行的,也会经常用到。其中@后面可以跟该元素任意的属性名。 b. 用start-with,定位代码如下: 1 driver.findElement(By.xpath(“//a)); 这句的意思是寻找rel属性以nofo开头的a元素。其中@后面的rel可以替换成元素的任意其他属性。 c. 用Text关键字,定位代码如下: 1 driver.findElement(By.xpath(“//*)); 这个方法可谓相当霸气啊。直接查找页面当中所有的退出二字,根本就不用知道它是个a元素了。这种方法也经常用于纯文字的查找。 另外,如果知道超链接元素的文本内容,也可以用 1 driver.findElement(By.xpath(“//a)); 这种方式一般用于知道超链接上显示的部分或全部文本信息时,可以使用。 最后,关于xpath这种定位方式,webdriver会将整个页面的所有元素进行扫描以定位我们所需要的元素,所以这是一个非常费时的操作,如果你的脚本中大量使用xpath做元素定位的话,将导致你的脚本执行速度大大降低,所以请慎用。 8. By.cssSelector() cssSelector这种元素定位方式跟xpath比较类似,但执行速度较快,而且各种浏览器对它的支持都相当到位,所以功能也是蛮强大的。 下面是一些常见的cssSelector的定位方式: 定位id为flrs的div元素,可以写成:#flrs 注:相当于xpath语法的//div 定位id为flrs下的a元素,可以写成 #flrs 》 a 注:相当于xpath语法的//div/a 定位id为flrs下的href属性值为/forexample/about.html的元素,可以写成: #flrs 》 a 如果需要指定多个属性值时,可以逐一加在后面,如#flrs 》 input。 明白基本语法后,我们来尝试用cssSelector方式来引用图(3)中选中的那个input对象,代码如下: WebElement password = driver.findElement(By.cssSelector("#J_login_form》dl》dt》input")); 同样必须注意层级关系,这个不能省略。 cssSelector还有一个用处是定位使用了复合样式表的元素,之前在第4种方式className里面提到过。现在我们就来看看如何通过cssSelector来引用到第4种方式中提到的那个button。button代码如下: 《button id="J_sidebar_login" class="btn btn_big btn_submit" type="submit"》登录《/button》 cssSelector引用元素代码如下: driver.findElement(By.cssSelector("button.btn.btn_big.btn_submit")) 。这样就可以顺利引用到使用了复合样式的元素了。 此外,cssSelector还有一些高级用法,如果熟练后可以更加方便地帮助我们定位元素,如我们可以利用^用于匹配一个前缀,$用于匹配一个后缀,*用于匹配任意字符。例如: 匹配一个有id属性,并且id属性是以”id_prefix_”开头的超链接元素:a 匹配一个有id属性,并且id属性是以”_id_sufix”结尾的超链接元素:a 匹配一个有id属性,并且id属性中包含”id_pattern”字符的超链接元素:a 最后再总结一下,各种方式在选择的时候应该怎么选择: 1. 当页面元素有id属性时,最好尽量用id来定位。但由于现实项目中很多程序员其实写的代码并不规范,会缺少很多标准属性,这时就只有选择其他定位方法。 2. xpath很强悍,但定位性能不是很好,所以还是尽量少用。如果确实少数元素不好定位,可以选择xpath或cssSelector。 3. 当要定位一组元素相同元素时,可以考虑用tagName或name。 4. 当有链接需要定位时,可以考虑linkText或partialLinkText方式。