python selenium自动化(一)点击页面链接测试
2013-12-08 22:47
393 查看
需求:现在有一个网站的页面,我希望用python自动化的测试点击这个页面上所有的在本窗口跳转,并且是本站内的链接,前往到链接页面之后在通过后退返回到原始页面。
要完成这个需求就必须实现3点:
1. 找到原始页面上面所有的在本窗口内跳转的链接
2. 跳转到目标页面之后,“后退”到原始页面
3. 在原始页面上继续点击后续的链接
首先,要找到页面上的所有链接并不困难。selenium为我们提供了find_elements_by_tag_name方法。我们只需要在初始化webdriver之后,调用
就能找到页面上的所有a标签。
我们可以对所有的a标签进行点击,但是这样的话我们不能保证所有的a标签所指向的目标页面都是站内的,有可能目标是其他的站外网页;另外这样也不能保证该跳转页面是在本窗口跳转而不是新开一个窗口。
解决办法:
使用selenium.webdriver.remote.webelement.WebElement提供的get_attribute方法。
通过get_attribute拿到该a标签的各种属性,通过判断找到符合要求的元素进行点击。
get_attribute("href") 得到a标签对应的目标页面的URL,对URL进行判断就可以了解到该页面是否站内页面。我们可以知道,如果是站内页面的话这个属性一般会是一个相对路径,或者包含了本站域名,但如果是站外页面的话,那它一定是包含了“http”的一个url。
get_attribute("target")如果target不是"_blank"的话,可以判断该页面是在本窗口跳转的。
跳转到下一页面后如何返回原始页面呢?
selenium webdriver 提供了back方法可以轻松的达到这个目标:driver.back()
最后,需要在返回了原始页面之后继续点击下一个链接进行测试,这个不用说肯定要使用for loop:
在python中,如果我们指定i在range(0, x)中循环时,会以1为步长来遍历从0到(x-1)的序列。例如:range(0,5)会得到[0, 1, 2, 3, 4]。当我们想更改range的步长时,则需要为range方法提供第三个参数。例如:range(0,5,2),则会以2为步长,得到[0,2,4]这个序列。
另外,我们也可以使用类似C#中foreach的方法:
这种方法同样可以遍历所有的a标签集合中的所有元素。
如果使用第二种方法,我们觉得这个需求可以简单的实现为:
但是这样的实现在运行时会抛出异常:
异常的说明已经很明显了:在cache中找不到元素,在元素被找到之后页面变换了。 这就说明,当当前页面发生跳转之后,存在cache中的关于这个页面的元素也被清空了。
因此,我们需要在每次回到原始页面之后对我们感兴趣的a标签元素重新搜索,同时我们又必须接着上次的点击到的元素继续点击。因此我们使用第一种遍历的方法来实现这个for loop:
这样,在每次返回页面之后会重新搜索一遍页面上的a元素,然后使用cache中的i继续点击下一个跳转链接。
要完成这个需求就必须实现3点:
1. 找到原始页面上面所有的在本窗口内跳转的链接
2. 跳转到目标页面之后,“后退”到原始页面
3. 在原始页面上继续点击后续的链接
首先,要找到页面上的所有链接并不困难。selenium为我们提供了find_elements_by_tag_name方法。我们只需要在初始化webdriver之后,调用
driver.find_elements_by_tag_name("a")
就能找到页面上的所有a标签。
我们可以对所有的a标签进行点击,但是这样的话我们不能保证所有的a标签所指向的目标页面都是站内的,有可能目标是其他的站外网页;另外这样也不能保证该跳转页面是在本窗口跳转而不是新开一个窗口。
解决办法:
使用selenium.webdriver.remote.webelement.WebElement提供的get_attribute方法。
通过get_attribute拿到该a标签的各种属性,通过判断找到符合要求的元素进行点击。
get_attribute("href") 得到a标签对应的目标页面的URL,对URL进行判断就可以了解到该页面是否站内页面。我们可以知道,如果是站内页面的话这个属性一般会是一个相对路径,或者包含了本站域名,但如果是站外页面的话,那它一定是包含了“http”的一个url。
get_attribute("target")如果target不是"_blank"的话,可以判断该页面是在本窗口跳转的。
跳转到下一页面后如何返回原始页面呢?
selenium webdriver 提供了back方法可以轻松的达到这个目标:driver.back()
最后,需要在返回了原始页面之后继续点击下一个链接进行测试,这个不用说肯定要使用for loop:
for i in range(0, len(driver.find_elements_by_tag_name("a"))):
在python中,如果我们指定i在range(0, x)中循环时,会以1为步长来遍历从0到(x-1)的序列。例如:range(0,5)会得到[0, 1, 2, 3, 4]。当我们想更改range的步长时,则需要为range方法提供第三个参数。例如:range(0,5,2),则会以2为步长,得到[0,2,4]这个序列。
另外,我们也可以使用类似C#中foreach的方法:
for targetLink in driver.find_elements_by_tag_name("a"):
这种方法同样可以遍历所有的a标签集合中的所有元素。
如果使用第二种方法,我们觉得这个需求可以简单的实现为:
links = driver.find_elements_by_tag_name("a") for link in links: if not "_blank" in link.get_attribute("target") and ("google" in link.et_attribute("href") or not "http" in link.get_attribute("href")): link.click() driver.back()
但是这样的实现在运行时会抛出异常:
selenium.common.exceptions.StaleElementReferenceException: Message: u'Element not found in the cache - perhaps the page has changed since it was looked up'
异常的说明已经很明显了:在cache中找不到元素,在元素被找到之后页面变换了。 这就说明,当当前页面发生跳转之后,存在cache中的关于这个页面的元素也被清空了。
因此,我们需要在每次回到原始页面之后对我们感兴趣的a标签元素重新搜索,同时我们又必须接着上次的点击到的元素继续点击。因此我们使用第一种遍历的方法来实现这个for loop:
length = len(driver.find_elements_by_tag_name("a") for i in range(0,length): links = driver.find_elements_by_tag_name("a") link = links[i] if not ("_blank" in link.get_attribute("target") or "http" in link.get_attribute("href")): link.click() driver.back()
这样,在每次返回页面之后会重新搜索一遍页面上的a元素,然后使用cache中的i继续点击下一个跳转链接。
相关文章推荐
- selenium 点击页面链接测试
- extjs点击左边的树的链接时链接在新页面展示
- QWebEngineView点击网页链接跳转页面
- Ruby on rails 点击链接,在新标签页打开页面
- HTML点击按钮或链接不跳转只刷新页面的方法
- 点击登陆链接在本页面弹出一个登陆窗口效果
- JavaScript 实现点击链接,多个页面内容同时改变的效果
- input点击链接另一个页面,各种操…
- android:WebView在没有网络情况下,点击当前页面内链接不跳转并弹出提示框
- spring Boot 项目之Thymeleaf模板 点击链接找不到模板页面异常-解决方案
- CCS bug之4: 站内发私人留言,用户同时收到email,点击链接,却显示该帖不存在的错误页面
- 如何点击链接直接跳转到app store指定应用下载页面
- 点击按钮或链接不跳转只刷新页面的脚本整理
- 把页面分成左右两个,如何实现在左侧点击,链接一个页面到右边的页面
- Android 通过URL scheme 实现点击浏览器中的URL链接,启动特定的App,并调转页面传递参数
- 点击链接让页面在iFrame切换里显示
- 点击datagrid的一行,然后链接到另一个页面
- 微信点击图文消息链接 在根据判断跳到另一个页面 但是 点关闭 将当前的关闭之后 会出现空白页
- javascript:void(0) ,设置a链接无效,设置点击a页面不刷新,不跳动