WebTest搭建

news2024/11/24 9:56:28

0.前言

此框架为真实项目实战,所以有些数据不便展示,只展示架构和思想

工具:python+selenium+ddt+unittest

1.架构说明

2.代码封装 

Commom层

base_page.py
#__author__=19044168
#date=2021/8/26
import logging
import datetime
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
import time
from Common import dir_config

from Common.logger import GetLogger
logger = GetLogger.get_logger()

#1.封装基本函数,执行日志,异常处理,失败截图
#2.所有的页面公共行为,非业务层面的行为
class BasePage:
    def __init__(self,driver):
        self.driver = driver

    #等待元素可见
    def wait_eleVisible(self,locator,wait_times=30,poll_frequency=0.5,doc=""):
        """
        :param locator: 元素定位元组形式(定位类型,定位方式)
        :param times:
        :param poll_frequency:
        :param doc: 模块名_页面名_操作名
        :return: None
        """
        logger.info("等待元素{0}可见".format(locator))
        try:
            #开始等待时间
            start = datetime.datetime.now().timestamp()#转化为s
            WebDriverWait(self.driver,wait_times,poll_frequency).until(EC.visibility_of_element_located(locator))
            # 结束等待时间
            end = datetime.datetime.now().timestamp()
            #求一个时间差值写到日志中
            sub_time = end - start
            logger.info("等待时长为:{}".format(sub_time))
            # self.save_screenshot(doc)
        except:
            logger.exception('等待元素可见失败!!!')
            #截图操作
            self.save_screenshot(doc)
            raise

    #待元素不可见
    def wait_eleNotVisible(self,locator,wait_times=30,poll_frequency=0.5,doc=""):
        """
        :param locator: 元素定位元组形式(定位类型,定位方式)
        :param times:
        :param poll_frequency:
        :param doc: 模块名_页面名_操作名
        :return: None
        """
        logger.info("{0}等待元素{1}不可见".format(doc,locator))
        try:
            # 开始等待时间
            start = datetime.datetime.now()  # 转化为s
            WebDriverWait(self.driver,wait_times, poll_frequency).until(EC.invisibility_of_element_located(locator))
            # 结束等待时间
            end = datetime.datetime.now()
            # 求一个时间差值,写到日志中
            wait_time = (end - start).seconds
            logger.info("{0}:元素{1}已可见,等待起始时间:{2},等待结束时间:{3},等待时长为:{4}".format(doc,locator,start,end,wait_time))
            # self.save_screenshot(doc)
        except:
            logger.exception('等待元素不可见失败!!!')
            # 截图操作
            self.save_screenshot(doc)
            raise

    #等待元素存在
    def wait_elePresence(self,locator,wait_times=30,poll_frequency=0.5,doc=""):
        logger.info("等待元素{0}存在".format(locator))
        try:
            # 开始等待时间
            start = datetime.datetime.now().timestamp()  # 转化为s
            WebDriverWait(self.driver, wait_times, poll_frequency).until(EC.presence_of_element_located(locator))
            # 结束等待时间
            end = datetime.datetime.now().timestamp()
            # 求一个时间差值写到日志中
            sub_time = end - start
            logger.info("等待时长为:{}".format(sub_time))
            # self.save_screenshot(doc)
        except:
            logger.exception('等待元素存在失败!!!')
            # 截图操作
            self.save_screenshot(doc)
            raise

    #查找元素
    def get_element(self,locator,doc=""):
        logger.info('{0}查找元素:{1}'.format(doc,locator))
        try:
            return self.driver.find_element(*locator)

        except:
            logger.exception("查找元素失败!!!")
            # 截图操作
            self.save_screenshot(doc)
            raise

    #点击操作
    def click_elemnet(self,locator,doc=""):
        #找元素
        ele = self.get_element(locator,doc)
        logger.info("{0}点击元素:{1}".format(doc,locator))
        #元素操作
        try:
            ele.click()
        except:
            logger.exception("点击元素失败!!!")
            # 截图操作
            self.save_screenshot(doc)
            raise

    #输入操作
    def input_text(self,locator,text,doc=""):
        # 找元素
        ele = self.get_element(locator,doc)
        logger.info("{0}输入元素{1}".format(doc,locator))
        try:
            ele.send_keys(text)
        except:
            logger.exception("输入元素失败!!!")
            # 截图操作
            self.save_screenshot(doc)
            raise

    #获取元素文本内容
    def get_text(self,locator,doc=""):
        ele = self.get_element(locator,doc)
        logger.info("{0}获取文本内容{1}".format(doc,locator))
        try:
            return ele.text
        except:
            logger.exception("获取文本内容失败!!!")
            # 截图操作
            self.save_screenshot(doc)
            raise

    #获取元素属性
    def get_element_attribute(self,locator,attr,doc=""):
        ele = self.get_element(locator, doc)
        logger.info("{0}获取元素{1}的{2}属性的值".format(doc,locator,attr))
        try:
            return ele.get_attribute(attr)
        except:
            logger.exception("获取元素属性失败!!!")
            # 截图操作
            self.save_screenshot(doc)
            raise

    # 获取所有句柄
    def get_handles(self,doc):
        logger.info("获取所有页面句柄")
        try:
            return self.driver.window_handles
        except:
            logger.exception("获取所有页面句柄失败!!!")
            # 截图操作
            self.save_screenshot(doc)
            raise

    # 获取当前句柄
    def get_current_handle(self, doc):
        logger.info("获取当前{}页面句柄".format(doc))
        try:
            return self.driver.current_window_handle
        except:
            logger.exception("获取获取当前页面句柄失败!!!")
            # 截图操作
            self.save_screenshot(doc)
            raise

    # 窗口切换
    def switch_window(self,handle,doc):
        logger.info("从当前窗口{}切换到指定窗口".format(doc))
        try:
            self.driver.switch_to.window(handle)
        except:
            logger.exception("切换窗口失败")
            self.save_screenshot(doc)
            raise

    #获取当前url
    def get_current_url(self,doc):
        logger.info("获取当前页面{}url".format(doc))
        try:
            return self.driver.current_url
        except:
            logger.exception("获取当前页面url失败")
            self.save_screenshot(doc)
            raise

    #移动到元素
    def move_to_element(self,target,doc):
        logger.info("{0},移动元素到{1}".format(doc,target))
        try:
            ActionChains(self.driver).move_to_element(target).perform()
        except:
            logger.exception("移动元素失败")
            self.save_screenshot(doc)
            raise

    #alert处理
    def alert_action(self,action='accept'):
        pass

    #iframe切换
    def switch_iframe(self,iframe_reference):
        pass

    #上传操作
    def upload_file(self):
        pass

    #截图操作
    def save_screenshot(self,doc):
        #图片名称:模块名_页面名_操作名_年-月-日-时-分-秒.png
        # now = datetime.datetime.now()
        # format_time = now.strftime("%Y-%m-%d-%H-%M-%S")
        # filename =  'OutPuts/screenshots/' + "{0}_{1}.png".format(name,format_time)
        # self.driver.save_screenshot(filename)
        # logging.info('截取网页成功,文件路径为{}'.format(filename))

        filePath = dir_config.screenshot_dir  + '/'+ '{0}_{1}.png'.format(doc,time.strftime("%Y-%m-%d-%H-%M-%S",time.localtime()))
        try:
            self.driver.save_screenshot(filePath)
            logger.info("截屏成功,截屏路径为{0}".format(filePath))
        except:
            logger.exception('截屏失败!!')
            raise

    #滚动条操作...


if __name__ == '__main__':
    pass

dir_config.py

email_fundation.py
#__author__=19044168
#date=2021/8/13
import smtplib
from email.mime.text import MIMEText#这是发正文
from email.mime.multipart import MIMEMultipart#这是发附件
import os

class Email:
    def __init__(self):
        self.send_user = 'xx@xxing.com'
        self.receive_user = 'yy@yying.com'
        # global user_list
        self.user_list = ['xx@xxing.com','ss4@ssing.com']
        self.server_host = 'smtp.suning.com'
        self.username = 'dfdds@ddning.com'
        self.password = 'dfsdfsdfsd'

    def sendEmail(self,new_file):
        f = open(new_file,'rb')
        mail_body = f.read()
        f.close()

        msg = MIMEMultipart('mixed')
        html_file = MIMEText(mail_body,'html','utf-8')
        # msg = MIMEMultipart(mail_body,'html','utf-8')
        msg['Subject'] = "Hbase WebAutoTest Report"
        context = MIMEText('<html><h2>您好,这是Hbase服务化测试报告</h2></html>', 'html', 'utf-8')
        msg.attach(context)
        msg.attach(html_file)

        # 发动邮件
        server = smtplib.SMTP()
        server.connect(self.server_host)
        server.login(self.username, self.password)
        # server.sendmail(self.send_user, self.receive_user, msg.as_string())
        server.sendmail(self.send_user, self.user_list, msg.as_string())
        server.close()

    def new_report(self,reportpath):
        lists = os.listdir(reportpath)
        lists.sort(key=lambda fn:os.path.getmtime((reportpath + '/' + fn)))
        print(lists)
        new_file = os.path.join(reportpath,lists[-1])
        print(new_file)
        return  new_file
e = Email()

if __name__ == '__main__':
    print(os.getcwd())
    e = Email()
    test_report = '../OutPuts/reports'
    new_report = e.new_report(test_report)
    e.sendEmail(new_report)

logger.py

#__author__=19044168
#date=2021/8/27
import logging.handlers
import time
from Common.dir_config import logs_dir

class GetLogger():
    logger = None

    @classmethod
    def get_logger(cls):
        if cls.logger == None:
            # 日志器实例
            cls.logger = logging.getLogger()

            # 设置日志级别
            cls.logger .setLevel(level=logging.INFO)

            # 控制台处理器实例
            ch = logging.StreamHandler()

            # 以时间切分日志文件处理器
            filename = logs_dir + '/' + time.strftime('%Y-%m-%d-%H-%M-%S') + '_WebUiTestLog.log'
            th = logging.handlers.TimedRotatingFileHandler(filename=filename,encoding='utf-8')

            # 设置日志格式
            fmt = "%(asctime)s %(levelname)s [%(name)s] [filename: %(filename)s - module: %(module)s - func: %(funcName)s  %(lineno)d line] - %(message)s"
            fm = logging.Formatter(fmt)

            # 将日志格式添加到处理器
            ch.setFormatter(fm)
            th.setFormatter(fm)

            # 将处理器添加到日志器
            cls.logger .addHandler(ch)
            cls.logger .addHandler(th)
        return cls.logger


if __name__ == '__main__':
    print(time.strftime())

OutPuts层,不需要封装,代码定义好目录即可

PageLocators层,根据页面层次进行组织

loginpage_locators.py,登录页面

 其他页面自行封装

PageObjects层,根据页面层次进行组织

login_page.py,登录页面
#__author__=19044168
#date=2021/8/19
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from PagesObjects.index_page import IndexPage
from PageLocators.loginpage_locators import LoginPageLocator as loc #直接用,不要继承,不然对象可选方法变量太多
from time import sleep

from Common.logger import GetLogger
logger = GetLogger.get_logger()

from Common.base_page import BasePage

class LoginPage(BasePage):
    # #用户名输入框
    # username_loc = (By.XPATH,'//input[@id="userId"]')
    # #密码输入框
    # password_loc = (By.XPATH,'//input[@id="password"]')
    # #登录按钮
    # login_loc = (By.XPATH,'//a[@id="submit_btn"]')
    # #是否记住密码勾选框
    # remember_loc = (By.XPATH,'//input[@id="remember"]')
    # #登录入口链接
    # enter_loc = (By.XPATH,'//a[@class="btn-login"]')
    # #用户名格式错误验证文本
    # errorMsg_from_wrongUser = (By.XPATH,'//div[@class="layui-layer-content"]')
    # #账号密码错误提示文本
    # msg_loc = (By.XPATH,'//div[@id ="error"]')

    # def __init__(self,driver):
    #     self.driver = driver

    #登录入口

    def login_enter(self):
        doc = '登录地址入口页面_登录跳转功能'
        self.wait_eleVisible(loc.enter_loc,doc=doc)

        self.click_elemnet(loc.enter_loc,doc=doc)

        # enter_loc = '//a[@class="btn-login"]'
        # WebDriverWait(self.driver,10).until(EC.visibility_of_element_located(loc.enter_loc))
        # self.driver.find_element_by_xpath(enter_loc).click()
        # self.driver.find_element(*self.enter_loc).click()#解包元组

        # self.driver.find_element(*loc.enter_loc).click()#解包元组

    #登录页面
    def login(self,username,password,is_remember=False):
        # 这些元素属性可以定义成类的属性,最好注释说明。但是有弊端,因为定位方式不止一种,修改定位就要修改元素操作方式
        # 不方便优化
        # username_loc = '//input[@id="userId"]'
        # password_loc = '//input[@id="password"]'
        # login_loc = '//a[@id="submit_btn"]'
        # remember_loc = '//input[@id="remember"]'

        # WebDriverWait(self.driver,10).until(EC.visibility_of_element_located(loc.username_loc))
        doc = "登录页面_登录功能"
        self.wait_eleVisible(loc.username_loc,doc=doc)

        self.input_text(loc.username_loc,username,doc=doc)
        self.input_text(loc.password_loc,password,doc=doc)

        # self.driver.find_element(*loc.username_loc).send_keys(username)
        # self.driver.find_element(*loc.password_loc).send_keys(password)

        #is_remember来判断是否需要记住账号密码
        if is_remember:
            # self.driver.find_element(*loc.remember_loc).click()
            self.click_elemnet(loc.remember_loc,doc=doc)
        else:
            pass

        # self.driver.find_element(*loc.login_loc).click()
        self.click_elemnet(loc.login_loc,doc=doc)

    #获取账号格式错误信息
    def get_errorMsg_from_wrongUser(self):
        # ret = self.driver.find_element(*loc.errorMsg_from_wrongUser)

        doc = "登录页面_账号格式错误信息"
        ret = self.get_text(loc.errorMsg_from_wrongUser,doc=doc)
        return ret

    #获取账号或者密码错误
    def get_errorMsg_from_pageCenter(self):
        doc = "登录页面_账号格式错误信息"
        self.wait_eleVisible(loc.msg_loc,doc=doc)
        # WebDriverWait(self.driver,10).until(EC.visibility_of_element_located(loc.msg_loc))

        ret = self.get_text(loc.msg_loc,doc=doc)
        return ret

    #帮助链接页面
    def help_link(self):
        current_handle = self.get_current_handle(doc="登录页面句柄")#其实也可以在base_page封装
        doc = "登录页面_帮助链接功能"
        self.wait_eleVisible(loc.help_link_loc,doc=doc)
        self.click_elemnet(loc.help_link_loc,doc=doc)
        handle = self.get_handles(doc="获取所有页面句柄")[-1]
        self.switch_window(handle,doc="帮助链接页面")#其实也可以在base_page封装

        help_url = self.get_current_url(doc='帮助链接页面')
        self.switch_window(current_handle,doc='登录页面')#其实也可以在base_page封装
        return help_url

    # 忘记密码链接页面
    def forget_pwd_link(self):
        current_handle = self.get_current_handle(doc="登录页面的句柄")#其实也可以在base_page封装
        doc = "登录页面_忘记密码链接功能"
        self.wait_eleVisible(loc.forget_pwd_link_loc,doc=doc)
        self.click_elemnet(loc.forget_pwd_link_loc,doc=doc)

        self.switch_window(self.get_handles(doc='获取所有页面句柄')[-1],doc='忘记密码链接页面')#其实也可以在base_page封装
        forget_pwd_url = self.get_current_url(doc='忘记密码链接url')#其实也可以在base_page封装

        self.switch_window(current_handle,doc='登录页面')#其实也可以在base_page封装
        return forget_pwd_url


if __name__ == '__main__':
    from selenium import webdriver
    from time import sleep
    from selenium.webdriver.common.action_chains import ActionChains

    driver = webdriver.Chrome()
    driver.maximize_window()
    driver.get('http://datakingdom.cnsuning.com/')
    lg = LoginPage(driver)
    ip = IndexPage(driver)
    lg.login_enter()

    # print(lg.help_link())
    # print(lg.forget_pwd_link())
    # lg.login_redirect()
    lg.login('19044168','19044168')
    sleep(1)

    driver.find_element_by_link_text('控制台').click()
    sleep(1)
    driver.find_element_by_xpath('//div[contains(text(),"平台基础服务")]').click()
    driver.find_element_by_css_selector('ul[role="menubar"] > li:nth-child(4) > ul > li:nth-child(1)').click()
    sleep(1)
    driver.find_element_by_xpath('//tr[2]//a').click()
    driver.find_element_by_xpath('//ul[@x-placement="bottom-end"]/li[contains(text(),"进入雨花prd环境")]').click()
    sleep(3)
    # print(lg.get_errorMsg_from_pageCenter())
    # target = driver.find_element_by_xpath('//div[@class="user-info"]')
    # ActionChains(driver).move_to_element(target).perform()
    # a = driver.find_element_by_link_text('退出')
    # print(a.text)

    # ip.isExist_logout_ele()
    driver.quit()




TestCases层

#__author__=19044168
#date=2021/8/20
from selenium import webdriver
import time
from PagesObjects.login_page import LoginPage
from PagesObjects.index_page import IndexPage
import unittest
from TestDatas import Common_Datas as CD
from TestDatas import Login_Datas as LD
import ddt

from Common.logger import GetLogger
logger = GetLogger.get_logger()

@ddt.ddt
class TestLogin(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        logger.info("======整个用例前置:打开浏览器,只执行一次=======")
        #通过excel获取本功能当中所需要的测试数据,但是比较麻烦。建议使用python文件保存测试数据
        cls.driver = webdriver.Chrome()
        cls.driver.maximize_window()
        cls.driver.get(CD.web_login_url)
        cls.lg = LoginPage(cls.driver)
        cls.lg.login_enter()#将该步骤提前到初始化步骤中,节省时间
        # cls.driver.save_screenshot()

    @classmethod
    def tearDownClass(cls):
        logger.info("=======整个用例后置:关闭浏览器,只执行一次=======")
        cls.driver.quit()

    #每个案例执行后进行页面刷新
    def tearDown(self):
        logger.info("=======每个用例后置:刷新一次页面======")
        self.driver.refresh()
        time.sleep(0.5)

    def test05_login_success(self):
        # self.lg.login_enter()#将该步骤提前到初始化步骤中,节省时间
        logger.info("=======登录用例:正常场景->登陆成功======")
        self.lg.login(LD.success_data['user'],LD.success_data['passwd'])
        self.assertTrue(IndexPage(self.driver).isExist_logout_ele(),'退出元素未出现')

    #异常用例--账号格式不正确(大于8位,小于8位,等于8位且包含非数字)
    #ddt,步骤断言都一致,只有文本内容不一致
    @ddt.data(*LD.user_data)
    def test01_login_wrongUserFormat(self,data):
        # self.lg.login_enter()#将该步骤提前到初始化步骤中,节省时间

        logger.info("=======登录用例:异常场景->账号格式错误,登陆失败======")
        self.lg.login(data['user'], data['passwd'])
        self.assertEqual(self.lg.get_errorMsg_from_wrongUser(),data['check'], '账号格式错误提示信息不对')

    # 异常用例--用户名或者密码错误
    @ddt.data(*LD.user_pwd_data)
    def test02_login_wrongUserOrPwd(self,data):
        # self.lg.login_enter()#将该步骤提前到初始化步骤中,节省时间

        logger.info("=======登录用例:异常场景->用户名或者密码错误,登陆失败======")
        self.lg.login(data['user'],data['passwd'])
        self.assertEqual(self.lg.get_errorMsg_from_pageCenter(),data['check'],'非用户名或密码错误')

    #帮助链接验证用例
    def test03_help_link(self):
        logger.info("=======登录帮链接用例:正常场景->帮助链接有效======")
        self.assertIn(LD.help_url,self.lg.help_link(),'帮助链接地址不包含在内')

    # 忘记密码链接验证用例
    def test04_forget_pwd_link(self):
        logger.info("=======登录忘记密码帮链接用例:正常场景->忘记密码链接有效======")
        self.assertIn(LD.forget_pwd_url,self.lg.forget_pwd_link(),'忘记密码链接地址不包含在内')


if __name__ == '__main__':
    unittest.main()

 TestDatas层

run.py

#__author__=19044168
#date=2021/8/27
import unittest
from HTMLTestRunner import HTMLTestRunner
from Common.dir_config import htmlreport_dir,testcases_dir
import time
from Common.send_mail_file import *
#实例化套件对象
suite= unittest.TestSuite()

#TestLoader的用法
#1.实例化Testloader对象
#2.使用discover去找到一个目录下的所有用例
#3.使用suite
loader = unittest.TestLoader()
# suite.addTests(loader.discover(testcases_dir,pattern='log*'))
suite.addTests(loader.discover(testcases_dir,pattern='*test.py'))

#运行
# runner = unittest.TextTestRunner()
# runner.run(suite)


cur_time = time.strftime("%Y-%m-%d-%H-%M-%S",time.localtime())
fp = open(htmlreport_dir + '/' + cur_time + '-AutoTest_report.html','wb')
runner = HTMLTestRunner(stream=fp,title='web测试报告',description="这是hbase的web测试报告",tester='小猪')
runner.run(suite)

e.sendEmail(e.new_report(htmlreport_dir))

 运行run.py文件即可

收工!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/417185.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据分析之道-NumPy(六)】数组操作

文章目录专栏导读1、修改数组形状reshape()resize()flatten()ravel()2、翻转数组transpose()flip()fliplr()flipud()3、修改数组维度newaxis()squeeze()4、连接数组concatenate()stack()hstack()、vstack()5、分割数组split()hsplit()vsplit()array_split()6、数组元素的添加和…

2023学习软件测试,如何月薪过万?这几条必须具备

软件测试&#xff0c;如何月薪过万&#xff1f; 这个问题换做前几年的功能测试或许还有点小难。但如今以点点点为主的功能测试&#xff0c;即将被淘汰&#xff0c;适者生存的法则下&#xff0c;自动化测试如雨后春笋登上舞台。 同一时间&#xff0c;随着各大互联网公司迅速扩…

Carla仿真二:Carla多视图切换代码详解

文章目录前言一、Carla多视图切换效果二、Camera安装坐标系1、Carla.Location2、Carla.Rotation三、接口及代码详解1、接口介绍2、生成上帝视图代码3、生成Camera视图代码四、完整代码前言 1、Carla提供了大量的Python API接口&#xff0c;用户可以通过查找文档实现各类功能&a…

【前缀和】

目录知识框架No.0 筑基No.1 普通前缀和题目来源&#xff1a;牛客网-NC14556&#xff1a;数圈圈题目来源&#xff1a;牛客网-NC14600&#xff1a;珂朵莉与宇宙题目来源&#xff1a;牛客网-NC21195 &#xff1a;Kuangyeye and hamburgers题目来源&#xff1a;牛客网-NC19798&…

混合开发中h5前端离线打包规范流程

1、离线化的目的 首先在H5Native的混合开发实战中&#xff0c;让人头疼最多的恐怕就是网页加载过程中的白屏了&#xff0c;以及弱网、断网状态下h5页面无法正常加载的问题&#xff0c;那么为了解决这些问题&#xff0c;我们H5端跟原生端共同讨论采用Hybrid App离线加载方案&…

fiddler(抓包)的用法和HTTP 协议的基本格式

目录 fiddler(抓包)用法&#xff1a; HTTP 协议的基本格式 HTTP请求&#xff1a; 首行 认识HTTP方法 GET和POST的典型区别&#xff1a; 认识请求“报头”&#xff08;header&#xff09; HTTP 响应 HTTP状态码&#xff1a; 状态码的分类&#xff1a; 认识响应 …

SD-WAN基本介绍

一、SD-WAN是什么&#xff1f;它能为我们带来什么&#xff1f; SD-WAN&#xff0c;即软件定义广域网络&#xff0c;是将SDN技术应用到广域网场景中所形成的一种服务。这种服务用于连接广阔地理范围的企业网络、数据中心、互联网应用及云服务&#xff0c;旨在帮助用户降低广域网…

STL——array和vector容器

&#x1f4d6;作者介绍&#xff1a;22级树莓人&#xff08;计算机专业&#xff09;&#xff0c;热爱编程&#xff1c;目前在c&#xff0b;&#xff0b;阶段>——目标Windows&#xff0c;MySQL&#xff0c;Qt&#xff0c;数据结构与算法&#xff0c;Linux&#xff0c;多线程&…

解密HTTP协议:探索其组成部分与工作原理

前言 欢迎来到今天的每日一题&#xff0c;每日一提。昨天有聊到&#xff0c;HTTP 和 HTTPS 之间有什么区别&#xff1f;面试官基本秉承着刨根问题的原则&#xff0c;肯定是不会轻易放过我们的&#xff0c;那么自然是要继续拷问了。所以我们今天就聊聊什么是 HTTP&#xff0c;它…

微服务分布式搜索引擎 Elastic Search RestClient 操作文档

文章目录⛄引言一、初始化 Java RestClient二、RestClient 对文档的CRUD操作⛅新增文档⏰查询文档⚡修改文档⌚删除文档三、RestClient 批量文档导入⛵小结⛄引言 本文参考黑马 分布式Elastic search Elasticsearch是一款非常强大的开源搜索引擎&#xff0c;具备非常多强大功能…

SpringBoot整合XXL-JOB

XXL-JOB&#xff1a; 官网文档地址&#xff1a;分布式任务调度平台XXL-JOB GitHub地址&#xff1a;https://github.com/xuxueli/xxl-job Gitee地址&#xff1a;https://gitee.com/xuxueli0323/xxl-job 拉取代码&#xff0c;首先执行一下doc/db下的sql文件 tables_xxl_job.sq…

JAVA识别电子发票问题汇总

之前写的java解析电子发票&#xff0c;上线后出现了一下线上的问题&#xff0c;无法解析发票&#xff0c;对问题做个规整&#xff0c;仅供参考&#xff01; 1. Pdfbox介绍 pdfbox是一款Apache的开源工具&#xff0c;可以进行对pdf进行操作&#xff0c;如题&#xff0c;转图片…

UE4C++学习篇(十九)-- 动画蒙太奇初级使用

用一个第三人称的射击案例来简单介绍一下动画蒙太奇的使用&#xff0c;动画蒙太奇的具体介绍这里就不多说了&#xff0c;不知道的小伙伴可以去搜一下了解。 这里介绍角色射击&#xff0c;射击的时候播放一个射击动画。 选中需要创建出动画蒙太奇的动画&#xff0c;点击创建&am…

物理服务器通过U盘安装CentOS 7操作系统

一、制作U盘启动盘 1、使用UltraISO工具打开需要安装的操作系统iso镜像文件&#xff08;我安装的是CentOS-7-x86_64-Minimal-2009.iso&#xff09;&#xff0c;如下图所示 镜像下载地址&#xff1a;centos-7.9.2009-isos-x86_64安装包下载_开源镜像站-阿里云 2、将该系统镜像…

nginx--官方模块

目录 1.概述 2.Nginx的客户端状态 1.使用 2.目录中选择一个随机主页 3.http内容替换 ​编辑 4.nginx请求限制 5.nginx访问控制 1.基于Ip的访问控制 1.1使用 1.2access_mod.conf 1.3只允许自己ip访问 1.4http_x_forwarded_for 1.5http_access_module局限性 2.基于…

【用python将文件夹下面的文件夹里面的文件全部提取出来,并且放到一个新的文件夹】

文件里面有多个文件&#xff0c;每个文件下面有很多jpg格式的照片&#xff0c;把所有照片提取出来并且放在一个新的文件夹下面。 可以使用Python的os和shutil库来完成这个任务。 比如说&#xff1a;我的faces95文件夹下面有95个文件&#xff0c;每个文件下面有十七到十八个照片…

深拷贝和浅拷贝

目录 一.Java的Cloneable和clone()方法 1.Object类中的clone() 2.实现Cloneable接口的类 3.通过clone()生成对象的特点 二.深拷贝和浅拷贝 1.浅拷贝 2.深拷贝 3.实现深拷贝的两种方法 1.一种是递归的进行拷贝 2.Json字符串的方式进行深拷贝 一.Java的Cloneable和clone…

No.037<软考>《(高项)备考大全》【第21章】项目组合管理

【第21章】项目组合管理1 考试相关2 项目组合管理2.1 项目组合管理、项目集管理、项目管理异同2.2 项目组合管理过程组3 练习题参考答案1 考试相关 选择1分必考 案例概率低&#xff0c;知识点看一遍即可 2 项目组合管理 1、项目组合是将项目、项目集&#xff0c;以及其他方面…

2023年MathorCup数学建模赛题浅析

MathorCup俗称妈杯&#xff0c;是除了美赛国赛外参赛人数首屈一指的比赛&#xff0c;而我们的妈杯今天也如期开赛。今年的妈杯难度&#xff0c;至少在我看来应该是2023年截至目前来讲最难的一场比赛。问题的设置、背景的选取等各个方面都吐露着我要难死你们的想法。难度是恒定的…

Servlet、SpringMVC、SpringBoot整合Thymeleaf汇总

介绍 模板引擎&#xff0c;与JSP、JSTL类似。 好处是&#xff1a;直接写在HTML文件中&#xff0c;服务器可以解析&#xff0c;浏览器也可以解析&#xff0c;实现了动静分离&#xff0c;并未破坏html结构&#xff0c;即使无网络、不通过后端渲染也能在浏览器成功打开&#xff…