Hello,大家好,又到了小猿分享技术的时间了。这回带来的是使用Selenium去网站上获取部分信息并且执行部分操作以及"含蓄"等待元素加载完成以及截取图片和网页刷新机制的技术点。

python使用selenium 来获取某一个网络请求_加载

 

 

  解释说明:Selenium用于自动化测试,web自动化测试工具集,即使用该模块去模拟手动去网页上点击获取信息,是一个很好的自动化测试模块。

python使用selenium 来获取某一个网络请求_自动化测试_02

 

 

  关于selenium模块,其实它的主要目的是进行web自动化测试,获取信息是次要的,主要是为了测试web的性能,这里也只是针对关于在web页面上进行操作。

大家在选用技术工具的时候要明白需求,选择合适的技术,做正确的事情

这里介绍一下selenium,官网介绍如下:

What is Selenium?
Selenium automates browsers. That's it! What you do with that
power is entirely up to you. Primarily, it is for automating 
web applications for testing purposes, but is certainly not 
limited to just that. Boring web-based administration tasks 
can (and should!) be automated as well.
Selenium has the support of some of the largest browser 
vendors who have taken (or are taking) steps to make Selenium
a native part of their browser. It is also the core technology
in countless other browser automation tools, APIs and frameworks.

重点是这一句:it is for automating web applications for testing purposes, but is certainly not limited to just that,翻译过来就是:它是用于自动化Web应用程序的测试目的,但肯定不仅仅限于此功能。简单来说它是Web的自动化测试工具集。因此单独拿出来讲述,它也是够学一阵子的。

Selenium的优点我不用细说,可以进行自动化测试,节省人力,可以全天化测试Web,过程可视化,可以全程观察到测试流程等等,但是缺点也是不可忽略的。

缺点:

速度慢:这点很让人捉急,因为每次运行都会打开一个浏览器,如果没有设置还会加载图片,JS等一堆东西。

占用资源太多:打开浏览器本身就会占用很多资源。

对网络要求更高:因为加载了图片,JS等资源,会产生更多的流量。

爬取规模不能太大:没有公司使用它作为生产环境。

:因为它是一个工具集,自然使用起来要比一个单纯的requests模块来说要困难点。所以这篇文章也仅仅是针对我在工作中用到的部分技术点做一下分享。

首先是获取页面上的标签,不论是使用selenium还是其他的爬虫技术, 我们需要做的都离不开定位标签, 即获取网页上的某元素,而selenium是打开浏览器,加载元素,由于网络原因或者其他的因素,页面上的元素不一定能同时加载出来,这就会导致产生ElementNotVisibleException错误出现,这样会降低自动化测试脚本的稳定性,所以我们要使用设置元素等待来解决这种问题造成的不稳定。

一,元素含蓄等待

WebDriver设置了两种类型的等待: 含蓄等待明确等待,明确等待即作用于特定代码,使之在某条件下成立才执行,比如设置个time.sleep(),或者是设置一下别的条件,使之执行。而含蓄等待则是属于智能等待,是全局超时设置,它不是固定的等待时间,一旦定位到元素就继续往下执行。相较而言,含蓄等待更是我们想要的,因为这个更符合我们的需求。需要导入的是 WebDriverWait模块

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
capabilities = {'chromeOptions': {'useAutomationExtension': False}}
driver = webdriver.Chrome(desired_capabilities=capabilities)
driver.maximize_window()
MAX_LOADING_TIME = 40
# 接下来我们要做的就是使用WebDriver语句去含蓄等待获取页面元素了。
# 语法是 WebDriverWait(driver, MAX_LOADING_TIME, 1).until(lambda x:x.find_element_by_xpath("//*[@id="main"]/div/div[2]/div[2]/div/div[2]/ul/li[3]"))

其作用是会在最大的加载时长内去获取该元素,一旦获取就往下执行,内部的lambda函数其实就是使用爬虫获取元素的方法,

方法如下:注意通过类名找元素需要注意有坑!!!

find_element_by_xpath
find_element_by_id
find_elements_by_class_name(注意使用该方法如果界面上不止一个该元素,
返回的是一个列表,如果想获取指定元素,需要使用索引进行取值) 例如
WebDriverWait(driver, MAX_LOADING_TIME, 1).until(
     lambda x: x.find_elements_by_class_name("addPoiToList"))[0]
需求场景

之前的一个业务逻辑是登录某个网站,获取某页面部分信息,接着去另一个页面去发送相应信息给别的用户,因为这些个操作比较麻烦,涉及页面切换,必然需要网络加载,因为这一切都是连续进行的,关系较为密切,因此任何一块如果操作失败都会导致整个测试案例的失败,而这个又是个核心,所以这一块的功能很重要,之前的逻辑是使用显示等待,到处都是time.sleep() word 天!!!晕菜又很low 逼。

装饰器,这个装饰器的作用是尝试执行封装的各个函数,当没有获取到某元素即出现异常时,会刷新网站页面, 接着再去尝试获取某元素,当再次失败时,再退出网页,此次测试结束,给的结果是执行某函数的功能失败。

二,装饰器

装饰器的结构如下:

import functools
def trigger_func_execute(be_executed_func):
    """
    Python decorator for execute the imported function with
    universal execution structure that is try to find 
    element in CCC if not find,refresh pages and search it
    again. if not find taking a screenshots and quit.
    :param be_executed_func:
    :return:
    """
    @functools.wraps(be_executed_func)
    def wrapper(current_normal_screenshot_path, 
                current_abnormal_screenshot_path, page_name):
        try:
            execution = be_executed_func(
                current_normal_screenshot_path,
                current_abnormal_screenshot_path)
            make_normal_selenium_screenshot(
                current_normal_screenshot_path,
                current_abnormal_screenshot_path, page_name)
            return execution
        except:
            try:
                driver.refresh()
                time.sleep(5)
                execution = be_executed_func(
                    current_normal_screenshot_path,
                    current_abnormal_screenshot_path)
                return execution
            except:
                make_abnormal_selenium_screenshot(
                    current_normal_screenshot_path,
                    current_abnormal_screenshot_path,
                    page_name)
                selenium_action['failed_step'] = 
                'Getting to %s Web page.' % wrapper.__name__
                return False

    return wrapper

其中使用了装饰器修复技术用来记录执行的函数名, 主要是用来记录下执行到哪一步函数出错了。

三,selenium截图

其中的

make_normal_selenium_screenshot 函数是用来在当执行某函数时正常情况下去截取一张图片,各个参数的意思是正常执行的图片存放路径,不正常存放路径,最后一个参数的意思是给截取的图片取的名字,使用的方法是,

driver.get_screenshot_as_file(file_path)

import time
def make_abnormal_selenium_screenshot(
    current_normal_screenshot_path, 
    current_abnormal_screenshot_path, 
    page_name):
    """
    Taking a screenshots of each page in CCC Backend.
    :param current_normal_screenshot_path
    :param page_name:each page name such as service_page
    :return:
    """

    screenshot_img_full_path = 
    current_abnormal_screenshot_path
    + '\\' + page_name + '_' + str(time.time()) + '.png'
    selenium_action['ccc_screenshot_img_full_path']
    = screenshot_img_full_path
    driver.get_screenshot_as_file(screenshot_img_full_path)

 

  这样整体实现的效果就是登录网站去进行操作,并在每一步关键的操作会截图,如果某元素不能捕获到,会刷新当前页面进行再次获取,如果再次获取不到,截取异常图片并且保留到异常的文件夹中,并且记录下来失败的那一项的函数名。

  关键点是划分清操作不同页面的范围,正确描述不同的操作步骤,这样在做我们的自动化测试过程中能让测试者很快理解步骤,对执行的结果也能很快定位出错误的位置,错误的原因以及其它必要的信息。

  总结就是使用了含蓄等待替代生硬的显示等待,使用装饰器避免代码的重复性,使用selenium截图保留事故现场。正常处理也进行截图方便后续分析。