PyAutoGUI实现对LoadRunner报告自动化截图

一、前言

对系统压测后,需要编写汇总报告。LoadRunner场景生成的Analysis报告,要截图保存部分图片。
每次几个功能,每个功能几个并发场景,每个场景有4张左右图片。太多重复性工作了,费时费力。
在这里插入图片描述

思考:怎么使用程序自动化截图
查资料:
pynput、pygetwindow和pyautogui是Python中用于鼠标和键盘控制的三个不同的库。
pynput库:提供了控制键盘和鼠标的功能。它可以监听和控制键盘的按键事件,以及移动鼠标和执行鼠标点击操作。它的特点是灵活性和控制选项更多,可以实现对键盘和鼠标的高级操作。
pygetwindow库:提供了管理和控制窗口的功能。它可以获取当前打开的窗口列表,并提供对窗口的操控和属性获取。它的特点是可以通过窗口的标题等属性来查找和操作指定的窗口。
pyautogui库:是一个自动化测试工具,用于模拟鼠标、键盘和屏幕的操作。它可以控制鼠标的移动、点击和拖放,模拟键盘按键和组合键,并可以对屏幕截图、识别图像等。它的特点是简单易用,适合于自动化任务和GUI测试。
最终选择了pyautogui,满足点击、截图等需求。

二、学习使用pyautogui库

查询pyautogui库方面的文章:
https://blog.csdn.net/hfy1237/article/details/127960423
https://blog.csdn.net/m0_57236802/article/details/129197537在这里插入图片描述

坐标的距离通过像素计算,如果你的屏幕分辨率是1920 x 1080,右下角的像素将是1919, 1079(因为坐标从0开始,而不是1)。

常用函数列表
函数名功能
基本pyautogui.size()返回包含分辨率的元组
pyautogui.PAUSE每个函数的停顿时间,默认0.1s
pyautogui.FAILSAFE是否开启防故障功能,默认True
键盘pyautogui.press('键盘字符')按下并松开指定按键
pyautogui.keyDown('键盘字符')按下指定按键
pyautogui.keyUp('键盘字符')松开指定按键
pyautogui.hotkey('键盘字符1', '键盘字符2')按下多个指定键
鼠标pyautogui.position()返回当前鼠标当前位置的元组
pyautogui.moveTo(x,y,duration=1)   按绝对位置移动鼠标并设置移动时间
pyautogui.moveRel(x_rel,y_rel,duration=4)  按相对位置移动鼠标并设置移动时间
pyautogui.dragTo(x, y, duration=1)   按绝对位置拖动鼠标并设置移动时间
pyautogui.dragRel(x_rel, y_rel, duration=4)  按相对位置拖动鼠标并设置移动时间
pyautogui.click(x, y) 鼠标点击指定位置,默认左键
pyautogui.click(x, y, button='left')鼠标单击左键
pyautogui.click(x, y, button='right')鼠标单击右键
pyautogui.click(x, y, button='middle')  鼠标单击中间,即滚轮
pyautogui.doubleClick(10,10) 鼠标左键双击指定位置
pyautogui.rightClick(10,10)鼠标右键双击指定位置
pyautogui.middleClick(10,10) 鼠标中键双击指定位置
pyautogui.scroll(10) 鼠标滚轮向上滚动10个单位

press(), keyDowm(),keyUp(),hotKey()支持的有效字符串列表如下:

类别
字母'a', 'b', 'c', 'd', 'e','f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
数字'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
符号'\t', '\n', '\r', ' ', '!', '"', '#', '$', '%', '&', "'", '(', ')', '*', '+', ',', '-', '.', '/', , ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~',
F键'f1', 'f10', 'f11', 'f12', 'f13', 'f14', 'f15', 'f16', 'f17', 'f18', 'f19', 'f2', 'f20', 'f21', 'f22', 'f23', 'f24', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9',
数字键盘'num0', 'num1', 'num2', 'num3', 'num4', 'num5', 'num6', 'num7', 'num8', 'num9', 
其他'accept', 'add', 'alt', 'altleft', 'altright', 'apps', 'backspace', 'browserback', 'browserfavorites', 'browserforward', 'browserhome', 'browserrefresh', 'browsersearch', 'browserstop', 'capslock', 'clear', 'convert', 'ctrl', 'ctrlleft', 'ctrlright', 'decimal', 'del', 'delete', 'divide', 'down', 'end', 'enter', 'esc', 'escape', 'execute', 'final', 'fn', 'hanguel', 'hangul', 'hanja', 'help', 'home', 'insert', 'junja', 'kana', 'kanji', 'launchapp1', 'launchapp2', 'launchmail', 'launchmediaselect', 'left', 'modechange', 'multiply', 'nexttrack', 'nonconvert', , 'numlock', 'pagedown', 'pageup', 'pause', 'pgdn', 'pgup', 'playpause', 'prevtrack', 'print', 'printscreen', 'prntscrn', 'prtsc', 'prtscr', 'return', 'right', 'scrolllock', 'select', 'separator', 'shift', 'shiftleft', 'shiftright', 'sleep', 'space', 'stop', 'subtract', 'tab', 'up', 'volumedown', 'volumemute', 'volumeup', 'win', 'winleft', 'winright', 'yen', 'command', 'option', 'optionleft', 'optionright'

三、实现

需求:一个文件夹内有很多Analysis报告,需要打开每一个报告,对summary report、Hits per Second、Average Transaction Response Time、Transactions per Second等页面进行截图保存。
思路
1、获取文件夹内Analysis报告的路径
2、打开Analysis软件
3、打开指定报告
4、截图、保存
5、重复3、4过程
6、关闭软件
实现

#!/usr/bin/env python 
# -*- coding:utf-8 -*-
import pyautogui
import pyperclip    #复制粘贴 文本复制到剪贴板
import subprocess   #管理子进程
import time
import os
import sys
import re
from PIL import Image
'''
功能:输入路径,扫描路径下2级目录中.lra文件,打开文件进行指定页面截图操作,截图保存在\image中。
设置:max_depth=2设置扫描目录深度,报告要默认有summary report、Hits per Second、Average Transaction Response Time页面,
    没有Transactions per Second页面可以新增。
    页面按钮位置与显示器分辨率有关,在cut()中调整。待匹配图片必须使用pyautogui.screenshot截取,才能匹配到。

'''

# pyautogui.screenshot('sa.png', region=(490,630,760,30)) #截取图标left,top,width,height
# sys.exit()

class lr_cut():

    def __init__(self,folder_path):
        '''
        获取报告路径、名称
        '''
        self.folder_path=folder_path                        # 设置报告文件夹路径
        max_depth=2                                         # 设置遍历文件深度
        self.file_paths=[]                                  # 全部报告路径
        self.file_names=[]                                  # 全部报告名称
        self.file_name=''                                   # 当前报告名称
        self.image_number=0                                 # 已截图报告数量
        for root, dirs, files in os.walk(folder_path, topdown=True):    # 遍历文件夹及其子文件夹中的.lra文件
            depth=root[len(folder_path):].count(os.sep)
            if depth > max_depth:                           # 深度超过限制,不继续递归
                del dirs[:]
            for file in files:
                if file.endswith('.lra'):                   # 条件筛选.lra
                    file_path=os.path.join(root, file)
                    self.file_paths.append(file_path)
        self.count=len(self.file_paths)                     # 统计报告数量
        if self.count == 0:
            print('扫描完成----------没有发现.lra格式的Analysis文件')
            sys.exit()                                      # 没有发现报告,程序退出
        else:
            print(f'扫描完成----------发现{self.count}个Analysis文件')
            pattern=r'[^\\]+(?=\.lra$)'                     # 提取路径中报告名称
            for file_path in self.file_paths:
                match=re.search(pattern, file_path)
                file_name=match.group()
                self.file_names.append(file_name)


    def number_one(self):
        '''
        打开软件,窗口最大化,截图
        '''
        # 打开LoadRunner软件(两种方式)
        # pyautogui.press('win')                            #[1]win搜索Analysis
        # pyautogui.typewrite('Analysis', 0.1)
        # pyautogui.press('enter')
        # pyautogui.press('enter')
        subprocess.Popen(['start', '', self.file_paths[0]], shell=True)  # [2]确保文件关联的程序能够正确打开.lra文件

        time.sleep(9)                                       # 等待LoadRunner启动
        self.file_name=self.file_names[0]                   # 文件名称

        screen_width, screen_height=pyautogui.size()        # 获取屏幕尺寸
        move_distance_x=screen_width // 2
        move_distance_y=screen_height // 2
        pyautogui.click(move_distance_x, move_distance_y)   # 确保文件打开窗口获得焦点
        pyautogui.hotkey('win', 'up')                       # 最大化窗口
        # pyautogui.hotkey('alt', 'space')
        # pyautogui.press('x')
        time.sleep(1)
        self.cut()


    def number_two(self,number):
        '''
        第二次打开文件(软件内打开文件),截图
        '''
        pyautogui.hotkey('ctrl', 'o')
        pyperclip.copy(self.file_paths[number])         # 将路径复制到剪贴板
        time.sleep(1)
        pyautogui.hotkey('ctrl', 'v')                   # 粘贴路径       绕过无法输入中文路径的问题
        pyautogui.press('enter')
        time.sleep(3)
        self.file_name=self.file_names[number]
        self.cut()


    def cut(self):
        '''
        对文件截图,保存在\image中。
        截图命名:报告名称-截图页面.png
        summary report界面匹配事务行数,调整截图高度
        tps截图时,没有tps则添加
        '''
        pyautogui.click(115, 150)  # 点击summary report 截图
        time.sleep(1)
        button_1=pyautogui.locateCenterOnScreen('sa.png', grayscale=True)   #匹配事务行数
        x, y=button_1
        y-=640
        k=351 + y
        name=f'image\\{self.file_name}-summary.png'
        pyautogui.screenshot(name, region=(488, 225, 762, k))       # 截图    每行高度20
        self.resize_screenshot(name)

        pyautogui.click(110, 200)  # 点击Hits per Second 截图
        time.sleep(1)
        name=f'image\\{self.file_name}-Hits.png'
        pyautogui.screenshot(name, region=(480, 100, 1412, 521))    # 截图
        self.resize_screenshot(name)

        k=521 + y
        pyautogui.click(165, 246)  # 点击Average Transaction Response Time 截图
        time.sleep(1)
        name=f'image\\{self.file_name}-Average.png'
        pyautogui.screenshot(name, region=(480, 100, 1412, k))      # 截图
        self.resize_screenshot(name)

        # tps截图,没有tps则添加
        button_position=pyautogui.locateCenterOnScreen('Transactions per Second.png', grayscale=True)  # 定位按钮图片的中心位置
        if button_position == None:
            pyautogui.hotkey('ctrl', 'a')       #添加tps图片
            time.sleep(1)
            button_position2=pyautogui.locateCenterOnScreen('Transactions.png', grayscale=True)
            pyautogui.doubleClick(button_position2)
            time.sleep(1)
            button_position=pyautogui.locateCenterOnScreen('Transactions per Second2.png')
            pyautogui.doubleClick(button_position)
            time.sleep(1)
            pyautogui.hotkey('alt', 'f4')
        pyautogui.click(button_position)
        time.sleep(1)
        name=f'image\\{self.file_name}-tps.png'
        pyautogui.screenshot(name, region=(480, 100, 1412, k))  # 截图
        self.resize_screenshot(name)

        #保存报告
        pyautogui.hotkey('ctrl', 's')
        time.sleep(1)
        self.image_number+=1            #截图报告数统计


    def resize_screenshot(self,name):
        '''
        调整图片大小
        '''
        screenshot=Image.open(name)        # 打开截图
        new_width=696                      # 缩小后的大小
        new_height=348
        resized_screenshot=screenshot.resize((new_width, new_height))       # 缩小截图
        resized_screenshot.save(name)      # 保存缩小后的截图


    def over(self):
        '''
        关闭软件,使用taskkill命令,避免出错后f4关闭其它软件
        '''
        # try:
        #     pyautogui.hotkey('alt', 'f4')
        # except Exception as e:
        #     print(f"pyautogui关闭失败,taskkill强制关闭")
        # finally:
        subprocess.run(["taskkill", "/im", "AnalysisUI.exe", "/f"])  # 使用taskkill命令终止指定的程序。/im参数指定终止程序名称,/f参数强制关闭程序
        print(f'应截报告{self.count}个,已截取报告{self.image_number}个')


    def main(self):
        '''
        1、打开软件,进行第一次截图
        2、在已打开软件内,循环打开文件、截图
        3、关闭软件
        '''
        try:
            self.number_one()
            if self.count > 1:                  # 报告数量>1,循环截图
                for i in range(1, self.count):
                    self.number_two(i)
            else:
                print('报告小于两个,已结束')
        except Exception as e:
            print(f"{self.file_name}--------截取中断:{e.__class__.__name__}")
        finally:
            self.over()



if __name__ == "__main__":
    folder_path = r'C:\Users\feng\Desktop'
    my_instance = lr_cut(folder_path)
    my_instance.main()
    #将鼠标移动到左上角将引发一个 pyautogui.FailSafeException 从而中断程序

效果
所有报告截图,图片存放在\image中。
鼠标移动到左上角,程序中断。
在这里插入图片描述

在这里插入图片描述
踩坑
开始编写代码移动鼠标,运行鼠标没有反应,百度后是权限问题。要管理员身份运行pycharm。

pyautogui.locateCenterOnScreen一直匹配不到按钮截图。百度后发现同样问题,解决方法:不能使用微信等截图工具,要使用pyautogui.screenshot(‘sa.png’, region=(490,630,760,30)),使用pyautogui自带的截图语句,好像是像素点不匹配。

所以要用上面代码的话,要自己根据屏幕分辨率设置点击坐标,重新使用pyautogui.screenshot截取按钮图片。
链接:https://pan.baidu.com/s/1YDy-x9U8sRL0tiza9SNMLA?pwd=a9d6
提取码:a9d6

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

觅梦_feng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值