一天教你使用Python3+selenium(三)

这篇博客快速介绍如何使用Python3结合selenium进行网页自动化操作。内容包括配置文件、基础页面类、入口脚本及日志模块的编写,适合想要速成的朋友。后续文章将补充更多内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

直接就要彪代码了,有点快了!这只是针对速成的朋友,要是想要认真学习,就去梦老师那里进行细致的学习

老规矩,依旧是从下往上开始

Config.config.ini

[environment]
browser = 1
switch = 0
用户名 = username

[test]
url = https://www.baidu.com/

[prod]
url = http://www.youdao.com/
yonghuming = username

[yonghu]
[sender]
username = 测试
email = 发送邮箱
password = 发送邮箱密码
[addressed]
user1 = 接收邮箱

famework

base_page.py

import configparser
from Logs.log import log1
from selenium import webdriver
import getcwd
import os
import time
path = getcwd.get_cwd()
config_path = os.path.join(path, 'Config/config.ini')

class BasePage():
    def config_options(self,section):
        '''读取配置文件某section下所有键'''
        config = configparser.ConfigParser()
        config.read(config_path,encoding="utf-8-sig")
        username = config.options(section)
        return username
 
 
    def get_addkey(self,user):
        '''遍历获得配置文件收件人email'''
        sum = 0
        L = []
        for i in user:
            if sum < len(user):
                emails = self.config_get(i,'addressed')
                L.append(emails)
                sum += 1
        return L
    
    
    
    def open_browser(self,driver):
        '''打开浏览器'''
        browser = self.config_get('browser','environment')
        log1.info('读取浏览器配置')
        url = self.config_get('url')
        log1.info('读取url:%s' % url)
        try:
            if browser == str(0) :
                driver = webdriver.Chrome()
                log1.info('打开的浏览器为谷歌')
            elif browser == str(1) :
                driver = webdriver.Firefox()
                log1.info('打开的浏览器为火狐')
            driver.get(url)
            driver.maximize_window()
            log1.info('浏览器最大化')
            driver.implicitly_wait(10)
            log1.info('设置静态等待时间10秒')
            return driver
        except BaseException:
            log1.error('浏览器打开报错')
           
    
    def config_get(self,key,section=None):
        '''读取配置文件字段的值并返回'''
        config = configparser.ConfigParser()
        config.read(config_path,encoding="utf-8-sig")
        switch = config.get('environment', 'switch')
        if section==None and switch == str(0):
            section = 'test'
        elif section==None and switch == str(1):
            section = 'prod'
        config_get = config.get(section,key)
        return  config_get
    def config_write(self,key = None,value = None,section = None):
        '''往配置文件写入键值'''
        config = configparser.ConfigParser()
        config.read(config_path,encoding="utf-8-sig")
        switch = config.get('environment', 'switch')
        if section == None and switch == str(0):
            section = 'test'
        elif section == None and switch == str(1):
            section = 'prod'
            '''
            原版
        if key is not None and value is not None:
            config.set(section,key,value)
            log1.info('在section:%s下写入%s=%s' %(section,key,value))
            with open(config_path,'w',encoding='utf-8')as f :
                config.write(f)
        else:
            config.add_section(section)
            log1.info('新增section:%s' % section)
            with open(config_path,'w',encoding='utf-8')as f :
                config.write(f)'''
        
        if  config.has_section(section) == True :
            '''我的'''
            if key is not None and value is not None:
                config.set(section,key,value)
                log1.info('在section:%s下写入%s=%s' %(section,key,value))
                with open(config_path,'w',encoding='utf-8')as f :
                    config.write(f)
            else:
                    print('youle')
                    log1.info('新增section:%s已存在哦' % section)
                    with open(config_path,'w',encoding='utf-8')as f :
                        config.write(f)
            
        elif config.has_section(section) == False:
            config.add_section(section)
            log1.info('新增section:%s' % section)
            with open(config_path,'w',encoding='utf-8')as f :
                config.write(f)
    def config_delete(self,key = None,section = None):
        '''删除配置文件字段'''
        config = configparser.ConfigParser()
        config.read(config_path,encoding="utf-8-sig")
        switch = config.get('environment', 'switch')
        if section == None and switch == str(0):
            section = 'test'
        elif section == None and switch == str(1):
            section = 'prod'
        if key is not None :
            config.remove_option(section,key)
            log1.info('删除section:%s下key为:%s的记录' % (section,key))
            with open(config_path,'w',encoding='utf-8')as f :
                config.write(f)
                print('1')
        else:
            config.remove_section(section)
            log1.info('删除section:%s' % section)
            with open(config_path,'w',encoding='utf-8')as f :
                config.write(f)
                print('122')
 
    def __init__(self,driver):
        '''与测试方法对应'''
        self.driver = driver
    def jin_frame(self,selector):
        '''进入frame'''
        element = self.find_element(selector)      
        self.driver.switch_to.frame(element)
        print("进入farm成功")
    def exit_frame(self):
        '''退出'''
        self.driver.switch_to.default_content()
    def find_element(self,selector):#元素定位
        '''元素定位'''
        by = selector[0]
        value = selector[1]
        element = None
        if by =='id' or by =='name' or by == 'class' or by == 'tag' or by =='link' or by =='text' or by =='css' or by == 'xpath' or by == 'text':
            if by == 'id':
                element = self.driver.find_element_by_id(value)
            elif by == 'name':
                element = self.driver.find_element_by_name(value)
            elif by == 'class':
                element = self.driver.find_element_by_class_name(value)
            elif by == 'tag':
                element = self.driver.find_element_by_tag_name(value)
            elif by == 'link':
                element = self.driver.find_element_by_link_text(value)
            elif by == 'text':
                element = self.driver.find_element_by_partial_link_text(value)
            elif by == 'css':
                element = self.driver.find_element_by_css_selector(value)
            elif by == 'xpath':
                element = self.driver.find_element_by_xpath(value)
            else:
                print('没有找到元素')
            print(element.is_displayed())
            return element
        else:
            print('输入的元素定位方式错误')
            
    def get_img(self):##
        '''截图'''
        
        path = os.path.join(getcwd.get_cwd(),'screenshots/')#拼接截图保存路径
        rq = time.strftime('%Y%m%d%H%M', time.localtime(time.time()))#按格式获取当前时间
        screen_name = path + rq + '.png'#拼接截图文件名
        print(screen_name)
        try:
            self.driver.get_screenshot_as_file(screen_name)
            log1.info("截图保存成功")
        except BaseException:
            log1.error("截图失败",exc_info = 1)

 
    def send(self,selector,value):
        '''写'''
        element=self.find_element(selector)#调用封装的定位元素方法
        try:
            element.send_keys(value)
            print('输入的内容%s' % value)
        except BaseException:
            print('error')
 
    

    def type(self,selector,value):
        '''输入内容'''
        element=self.find_element(selector)
        element.clear()
        log1.info('清空输入内容')
        try:
            element.send_keys(value)
            log1.info('输入的内容:%s' % value)
        except BaseException:
            log1.error('内容输入报错',exc_info = 1)
            self.get_img()
 
 
    def click(self,selector):
        '''点击元素'''
        element = self.find_element(selector)
        try:
            element.click()
            log1.info('点击元素成功')
        except BaseException:
            log1.error('点击元素报错',exc_info = 1)
            self.get_img()
 
 
    def sleep(self,secondes):
        '''强制暂停'''
        time.sleep(secondes)
        log1.info('暂停%d秒' % secondes)
 
 
    def get_title(self):
        '''获取title'''
        title = self.driver.title
        log1.info('当前窗口的title是:%s' % title)
        return  title
 
    def quit(self):
        self.driver.quit()
        log1.info('关闭浏览器')
    def dangqianwangye(self):
        '''获取句柄,并转进来'''
        sreach_window=self.driver.current_window_handle
        print(sreach_window)
        log1.info('当前句首:%s' % sreach_window)
        return  sreach_window

entrance.py

'''
Created on 2019年4月26日

@author: NULL
'''
'''
import text.text
import unittest

if __name__ == "__main__":
    suite = unittest.TestSuite()
    suite.addTest(text.text.test_baidu('test_baisu'))
    runner = unittest.TextTestRunner()
    runner.run(suite)
    '''
from famework.my_email import mail
import text.text
import text.test_baidu_new
import unittest
import getcwd
import os
import HTMLTestRunnerCN
 
if __name__ == "__main__":
    suite = unittest.TestSuite()
    suite.addTest(text.text.test_baidu('test_baisu'))
    suite.addTest(text.test_baidu_new.test_baidu_new('test_new'))
    path = getcwd.get_cwd()
    file_path = os.path.join(path,'report/xxxUI自动化测试报告.html')
    fp = open(file_path,'wb')
    runner = HTMLTestRunnerCN.HTMLTestReportCN(
        stream = fp,
        title = 'xxxUI自动化测试报告',
        description = '报告中描述部分',
        tester = '测试者'
    )
    runner.run(suite)
    fp.close()
    mail()

my_email.py另一种写法是的,我还没实行。有会的大佬可以写一下。密码不是自己的密码

'''
Created on 2019年4月30日

@author: NULL
'''
import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr
from email.mime.multipart import MIMEMultipart
import getcwd
import os
from Logs.log import log1
from famework.base_page import BasePage
import time
 
rq = time.strftime('%Y%m%d', time.localtime(time.time()))#获取本地时间 转换成日期
my_mail = BasePage(driver=1)
sender = my_mail.config_get('email','sender')  # 发件人邮箱账号
password = my_mail.config_get('password','sender')  # 发件人邮箱密码
usernmae = my_mail.config_get('username','sender') #发件人姓名
users = my_mail.config_options('addressed')     #收件人
addressed_eamils = my_mail.get_addkey(users)  #收件人邮箱
 
path = getcwd.get_cwd()
file = os.path.join(path, 'report/xxxUI自动化测试报告.html')
 
def mail():
    try:
        # 创建一个带附件的实例
        message = MIMEMultipart()
        message['From']=formataddr([usernmae,sender])  # 括号里的对应发件人邮箱昵称、发件人邮箱账号
        log1.info('发件人姓名:%s' % usernmae)
        log1.info('发件人邮箱:%s' % sender)
        message['To']=';'.join(addressed_eamils)    # 括号里的对应收件人邮箱昵称、收件人邮箱账号
        log1.info('收件人邮箱:' + ';'.join(addressed_eamils))
        message['Subject']=rq + "xxxUI自动化测试报告.html"    # 邮件的主题,也可以说是标题
 
        # 邮件正文内容
        message.attach(MIMEText('附件为xxxUI自动化测试报告.html', 'plain', 'utf-8'))
 
        # 构造附件1,传送当前目录下的 test.txt 文件
        att1 = MIMEText(open(file, 'rb').read(), 'base64', 'utf-8')
        log1.info('读取附件')
        att1["Content-Type"] = 'application/octet-stream'
        # 这里的filename可以任意写,写什么名字,邮件中显示什么名字
        att1.add_header("Content-Disposition", "attachment", filename=("gbk", "", "xxxUI自动化测试报告.html"))
        # 附件名称非中文时的写法
        # att["Content-Disposition"] = 'attachment; filename="test.html")'
        message.attach(att1)
        log1.info('添加附件')
 
        server = smtplib.SMTP_SSL("smtp.qq.com", 465)  # 发件人邮箱中的SMTP服务器,端口是25
        log1.info('连接QQ邮箱smtp服务')
        server.login(sender,password)  # 括号中对应的是发件人邮箱账号、邮箱密码
        log1.info('连接成功')
        server.sendmail(sender, addressed_eamils, message.as_string())  # 括号中对应的是发件人邮箱账号、收件人邮箱账号、发送邮件
        server.quit()  # 关闭连接
        log1.info("邮件发送成功")
    except Exception:
        log1.error("邮件发送失败",exc_info=1)
'''另一种写法'''
'''’
#发邮件的库
import smtplib
#邮件文本
from email.mime.text import MIMEText
#SMTP服务器
SMTPSever = "smtp.163.com"
#发邮件的地址
sender = ""
#发送者邮箱的密码(授权码)
passwd = ""
#设置发送的内容
message = "你好"
#转换成邮件文本
msg = MIMEText(message)
#标题
msg["Subject"] = "来自帅哥的问候"
#发送者
msg["From"] = sender
#创建SMTP服务器
mailSever = smtplib.SMTP(SMTPSever,25)
#登录邮箱
mailSever.login(sender,passwd)
#发送邮件
mailSever.sendmail(sender,["接受的邮箱"],msg.as_string())
#退出邮箱
mailSever.quit()'''

logs.log.py

#-*- coding: UTF-8 -*-
import logging
import time
import os
import getcwd
def get_log(logger_name):
 
        #创建一个logger
        logger= logging.getLogger(logger_name)
        logger.setLevel(logging.INFO)
 
        #设置日志存放路径,日志文件名
        #获取本地时间,转换为设置的格式
        rq = time.strftime('%Y%m%d%H%M',time.localtime(time.time()))
        #设置所有日志和错误日志的存放路径
        path = getcwd.get_cwd()
        #通过getcwd.py文件的绝对路径来拼接日志存放路径
        all_log_path = os.path.join(path,'Logs/All_Logs/')
        error_log_path = os.path.join(path,'Logs/Error_Logs/')
        #设置日志文件名
        all_log_name = all_log_path + rq +'.log'
        error_log_name = error_log_path + rq +'.log'
 
        #创建handler
        #创建一个handler写入所有日志
        fh = logging.FileHandler(all_log_name)
        fh.setLevel(logging.INFO)
        #创建一个handler写入错误日志
        eh = logging.FileHandler(error_log_name)
        eh.setLevel(logging.ERROR)
        #创建一个handler输出到控制台
        ch = logging.StreamHandler()
        ch.setLevel(logging.INFO)
 
        #定义日志输出格式
        #以时间-日志器名称-日志级别-日志内容的形式展示
        all_log_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        #以时间-日志器名称-日志级别-文件名-函数行号-错误内容
        error_log_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(module)s  - %(lineno)s - %(message)s')
        #将定义好的输出形式添加到handler
        fh.setFormatter(all_log_formatter)
        ch.setFormatter(all_log_formatter)
        eh.setFormatter(error_log_formatter)
 
 
        #给logger添加handler
        logger.addHandler(fh)
        logger.addHandler(eh)
        logger.addHandler(ch)
        return  logger
 
log1 = get_log("selenium")
 

后续,下一篇文章补上

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值