python异常处理、对象编程、pytest、fixture、正则、爬虫、爬取正文、知识点

异常处理

#
#一个标准的try except语句,至少要有一个except,也可以有多个except,也可以加一个else语句,以及finally语句
 try:
     int1=int(input('请输入一个整数'))
     print(1/int1)
 except ZeroDivisionError:
     print('0不能作为分母')
 except ValueError:
     print('您输入的不是整数')
 except:  #以上的异常没有捕捉到的情况下,此处起到兜底的作用
     print('程序有问题')
 else:  #程序未出现异常,则执行else中的语句
     print('没有出现异常')
 finally:  #无论程序是否出现异常,都会执行
     print('程序运行完毕')

#常见的异常
# NameError  #未定义的变量
# print(num1)
# IndexError
# list1=[10,20]
# print(list1[2])
# IOError  #输入输出异常
# FileNotFoundError
 with open('D:/中国足球勇夺世界杯冠军.txt') as file1:
     file1.read()

#所有的异常,都是Exception的子类或者子类的子类
 print(NameError.__bases__)
 print(IndexError.__bases__)
 print(LookupError.__bases__)
#Exception也有一个父类,BaseException
 print(Exception.__bases__)
 print(BaseException.__bases__)

#手动抛出异常
 try:
     raise IOError  #假装这里有异常
 except:
     print('文件读写错误')

#日志模块
import time  #加载时间模块
import logging  #加载日志模块
import traceback  #加载配合日志的异常模块
logging.basicConfig(level='DEBUG',filename='D:/log_210315.log',filemode='a+')
 logging.debug('这是debug级信息')
 logging.info('这是info级信息')
 logging.warning('这是warning级信息')
 logging.error('这是error级信息')
 logging.critical('这是critical级信息')
try:
    int1=int(input('请输入一个整数'))
    print(1/int1)
except ZeroDivisionError:
    logging.error(time.strftime('%y-%m-%d %H:%M:%S')+traceback.format_exc())
except ValueError:
    logging.error(time.strftime('%y-%m-%d %H:%M:%S')+traceback.format_exc())
except:  #以上的异常没有捕捉到的情况下,此处起到兜底的作用
    print('程序有问题')
else:  #程序未出现异常,则执行else中的语句
    logging.info('服务器未出现异常')
finally:  #无论程序是否出现异常,都会执行
    print('程序运行完毕')

#课堂小结
#try,excpet,else,finally
#常见的异常
#所有的异常都是Exception的子类
#手动抛出异常 raise
#将异常写入日志

第9次课思考题讲解


#解题思路
#1.建立一个老虎的类
#2.建立一个羊的类
#3.建立一个房间的类
#4.把老虎或者羊放入房间
#5.写游戏相关的代码
class Tiger:
    def __init__(self):
        self.name='老虎'
        self.weight=200
    def eat(self,food):
        if food=='meat':
            print('喂食正确')
            self.weight+=10
        elif food=='grass':
            print('喂食错误')
            self.weight-=10
    def roar(self):
        print('Wow!')
        self.weight-=5

class Sheep:
    def __init__(self):
        self.name='羊'
        self.weight=100
    def eat(self,food):
        if food=='grass':
            print('喂食正确')
            self.weight+=10
        elif food=='meat':
            print('喂食错误')
            self.weight-=10
    def roar(self):
        print('mie~')
        self.weight-=5

#建立一个房间的类
class Room:
    def __init__(self,category):
        self.category=category

roomlist=[]  #定义一个列表,等下用来存放房间的实例

from random import randint
for i in range(10):
    if randint(1,2)==1:  #相当于扔硬币决定是生成老虎还是生成羊
        category=Tiger()  #实例化一个老虎
    else:
        category=Sheep()  #实例化一个羊
    rm=Room(category)  #实例化一个房间,里面有一个动物
    roomlist.append(rm)  #把房间的实例放到列表中

import time
start_time=time.time()  #记录游戏开始时间
while time.time()-start_time<=10:
    room_number=randint(0,9)  #随机选择一个数字作为房间号
    random_room=roomlist[room_number]  #选取该房间
    load1=input(f'当前访问的是{room_number+1}号房间,请问是敲门还是喂食?1/2')
    if load1=='1':
        random_room.category.roar()  #调用房间中的动物的叫的方法
    elif load1=='2':
        food=input('请输入需要喂的食物 meat/grass')
        if food=='meat' or food=='grass':
            random_room.category.eat(food)  #调用房间中的动物的吃的方法
        else:
            print('您输入的食物不正确')
    else:
        print('您输入的操作不正确')
else:
    print('游戏时间到')
    for i in range(len(roomlist)):
        print(f'{i+1}号房间的动物是{roomlist[i].category.name},体重是{roomlist[i].category.weight}')

正则表达式

#正则表达式,其实就是从一段字符串中提取出需要的字符
import re  #加载正则表达式模块
re.findall(参数1,参数2,参数3)  参数1表示用什么规则进行提取,参数2表示从哪个字符串进行提取
#参数3一般有re.I 表示不区分大小写,re.S 匹配多行中满足条件的值
str1='abcdefg'
#. 通配符,匹配某个字符前面或后面的一个字符
 print(re.findall('a.',str1))  #提取a后面的一个字符,返回值是列表,包括条件a也返回
 print(re.findall('a(.)',str1))   #提取a后面的一个字符,返回值是列表,不包括条件a

#* 通配符,匹配某个字符后面的若干个字符,若干也包括0个的情况
 str1_1='abcdabbcbbbbeafg'
 print(re.findall('ab*',str1_1))  #把所有a后面有若干个b的字符找出来,包括0个b的情况

#? 通配符,匹配某个字符串后面有0-1个字符
 str1_2='abacabbbbbd'
 print(re.findall('ab?',str1_2))

#+ 通配符,匹配某个字符串后面有一个或多个字符,不包括0个的情况
 print(re.findall('ab+',str1_2))

#.*?  提取字符串两端之间的内容  A(.*?)B
load1='一二三四五六七八九'
print(re.findall('三(.*?)六',load1))

#如果只有一端给出了条件,值会怎么取?
 print(re.findall('三(.*?)六',load1))  #懒惰匹配,在符合查询要求的情况下,尽可能少的匹配
 print(re.findall('(.*?)六',load1))  #需要匹配的字符串后面是'六',无法偷懒

#只给出一端的条件时,如果希望获取后面全部的结果,则应当使用贪婪匹配
 print(re.findall('三(.*)六',load1))  #贪婪匹配

#当有多个满足条件的值时,两者的结果并不相同
load1='一二六三四五六三七八九六'
 print(re.findall('三(.*?)六',load1))  #懒惰匹配
 print(re.findall('三(.*)六',load1))  #贪婪匹配

#如果没有满足条件的查询,返回空列表
 print(re.findall('九(.*?)一',load1))  #懒惰匹配
 print(re.findall('九(.*)一',load1))  #贪婪匹配

#\w{n}  匹配字母,数字,下划线,n表示连续满足条件的位数
str3='nyrbt'
 print(re.findall('\w{3}',str3))

#\W 匹配\w的补集
 str3_new='ny#$%rbt'
 print(re.findall('\W{3}',str3_new))

#\s 匹配空格,换行符\n,制表符\t
str6='''小娃撑小艇,
偷采白莲    回.
不解藏踪    迹,
浮萍一道    开
'''
 print(re.findall('\s',str6))
#\S \s的补集
 print(re.findall('\S',str6))

#^匹配开头,$匹配结尾
 list1=['abcde','deabc','fabcf']
 for one in list1:
     if re.findall('^abc',one):  #匹配以abc开头的字符串
         print(one,'以abc开头')
     elif re.findall('abc$',one):  #匹配以abc结尾的字符串
         print(one,'以abc结尾')

#re.I  不区分大小写
 req='AbcabcABcaBCabCABC'
 print(re.findall('abc',req,re.I))

#re.S 匹配多行中符合条件的值
 req2='''hellounyrbtyutnhbgumynhbg
 ,imyuntbuimyuntybr
 68,imyuntybrytnuymi,oumworld'''
 print(re.findall('hello(.*?)world',req2,re.S))

#课堂小结
#正则表达式的通配符 . * ? +
#加()和不加()的区别
#.*? 懒惰匹配 .* 贪婪匹配
#\w,\s
#re.I,re.S

网络爬虫


import re
import requests
url='https://www.xs4.cc/chapter/?870.html'  #需要爬取的网址
req=requests.get(url)
req.encoding='gbk'  #将编码转为gbk格式
book_name=re.findall('<h1>(.*?)</h1>',req.text)[0]  #取得书名
mulu=re.findall('title="(第.*?)">第',req.text)  #取得所有章节的目录
# for i in range(1,len(mulu)):
#     print(mulu[i])
wangzhi=re.findall('<a href="article(.*?).html"',req.text)  #取得所有章节的正文网址
# for i in range(1,len(wangzhi)):
#     print(f'https://www.xs4.cc/article{wangzhi[i]}.html')
dict1={}
for i in range(1,len(mulu)):
    dict1[mulu[i]]=f'https://www.xs4.cc/article{wangzhi[i+1]}.html'
for k,v in dict1.items():
    print(k,v)

爬取全书网正文


import re
import os
import requests
import xlwt,xlrd
 url='https://www.qzguermei.com/d/1020/'
 req=requests.get(url)
 name=re.findall('<h1>(.*?)</h1>',req.text)[0]  #取得书名
 mulu=re.findall('html" title="(.*?)" target="_blank"',req.text)  #获取目录
 wangzhi=re.findall('<a href="/d/1020/(.*?).html" title="',req.text)  #获取网址
 dict1={}
 for i in range(14,len(mulu)):
    dict1[mulu[i]]=f'{url}{wangzhi[i]}.html'


#写入文件
 excel1=xlwt.Workbook()  #实例化一个excel
 worksheet=excel1.add_sheet(f'{name}')  #新建一个sheet
 worksheet.write(0,0,'目录')  #行,列,值
 worksheet.write(0,1,'网址')  #行,列,值
 row=1
 for k,v in dict1.items():
     worksheet.write(row,0,k)  #将目录写入到excel
     worksheet.write(row,1,v)  #将网址写入到excel
     row+=1
 excel1.save(f'd:/{name}.xls')

#读取excel
 data=xlrd.open_workbook(f'd:/{name}.xls')  #读取一个excel文件
 sheet1=data.sheets()[0]  #读取第一个sheet
 for i in range(1,sheet1.nrows):  #nrows 返回有效行数
     print(sheet1.cell_value(i,0),sheet1.cell_value(i,1))

#获取正文内容
 if not os.path.exists(f'd:/{name}'):  #判断目录是否存在,如果不存在,则
     os.mkdir(f'd:/{name}')  #新建一个以书名命名的目录
 count=1
 for k,v in dict1.items():
     if count>=5:
         break
     else:
         zhengwen=requests.get(v)  #获取正文网页的内容
         neirong=re.findall('id="chaptercontent">(.*?)全书网手机阅读地址',zhengwen.text,re.S)[0]  #获取正文内容
         neirong=neirong.replace('&nbsp;','').replace('<br/><br/>','\n')  #去掉多余的字符
         with open(f'd:/{name}/{count:04}_{k}.txt','w+') as file1:
             file1.write(neirong)
     count+=1

#阶乘
# 6!=6*5!
# 5!=5*4*3*2*1
#
# n!=n*(n-1)!
#递归
def jiecheng(n):
    if n==1:
        return 1
    else:
        return n*jiecheng(n-1)
print(jiecheng(6))

pytest

#pytest是一种自动化测试框架,是python的第三方单元测试框架,向下兼容unittest
#预期结果,实际结果
pip install pytest,或者使用豆瓣源,清华源等进行安装

#pytest命名规范
#文件名应当以test_开头,或者以_test结尾
#类应当以Test开头,且类当中不能有__init__方法
#方法或函数应当以test_开头
#断言必须使用assert  结果为真,断言不做事情,结果为假,断言生效,抛出异常AssertionError

 assert 1==2  #判断等式两边是否相等
 assert 200  #判断某个语句是否为真
 assert 10 in [10,20]  #判断某个值是否属于某个对象
 assert 1!=2  #判断某个值是否不等于另一个值
 assert not False

import pytest
import allure
import os  #加载系统模块
 def test_01():
     print('HelloWorld')
     assert 1==1  #判断预期结果和实际结果是否一致
 def test_02():
     assert 1==2

 class Test1:
     def teardown_method(self):  #④
         print('这是最后执行的方法')
     def test_c01(self):  #②
         assert 10==100
     def test_c02(self):  # ③
         assert 1 == 1
     def setup_method(self):  #①
         print('这是最先执行的方法')
#method级别 ①②④①③④

# class Test1:
     def teardown_class(self):  #④
         print('这是最后执行的方法')
     def test_c01(self):  #②
         assert 10==100
     def test_c02(self):  # ③
         assert 1 == 1
     def setup_class(self):  #①
         print('这是最先执行的方法')
#class级别  ①②③④

 class Test10:
     @pytest.mark.parametrize('result,real_result',[[3,6],[6,9],[18,18]])  #数据驱动,参数化
     def test_10(self,result,real_result):
         assert result==real_result

@allure.feature('层级1')
@allure.story('层级2')
@allure.title('层级3')
class Test20:
    def test_20(self):
        assert 3+6==9
#pytest框架,测试通过,显示".",测试不通过,显示F
if __name__ == '__main__':
    pytest.main(['test_pytest210319.py','-s','--alluredir','./report'])  #test_pytest210319.py 文件名 -s展示打印的语句
    os.system('allure generate ./report -o ./report/report --clean')

#课堂小结
#pytest框架的概念,命名规范
#assert断言
#pytest的写法
#setup,teardown,@pytest.fixture(scope='class')
#数据驱动 @pytest.mark.parametrize

#allure环境搭建
# 1、下载allure.zip
# 2、解压allure.zip到一个文件目录中
# 3、将allure报告安装目录\bin所在的路径添加环境变量path中
# 4、pip install  allure-pytest
# 5、验证

fixture

#test_example1
import pytest
@pytest.fixture(scope='class')  #装饰器,相当于setup_method
# 缺省级别为function级,可以使用scope='class'更改级别
#scope='module'
#scope='session' 选择这个级别时,将fixture的内容写到conftest.py中,目录下的所有文件共用这个配置
def some_data():
    print('开始')
    yield  #这句话以下的内容,视为teardown_method
    print('结束')
def test_some_data(some_data):
    print('test')
if __name__ == '__main__':
    pytest.main(['test_example1.py','-s'])

#将九九乘法表写入文件
with open ('d:/九九乘法表_210319.txt','w+') as file1:
    for i in range(1,10):
        for j in range(1,i+1):
            file1.write(f'{j}*{i}={i*j}\t')
        file1.write('\n')

python知识点复习上

#单引号,双引号,三引号
 str1="It's OK"
 print(str1)
 str2='He said:"Are you OK?"'
 print(str2)
 str3="""He said:"Are you OK?",It's OK"""
 print(str3)
 str3_new='''空山不见人
 但闻人语响
 返景入深林
 复照青苔上'''
 print(str3_new)

#字符串的拼接
 print('A'+'B')
 print('1'+'6')
 print('1'*'6')  #报错
 print('1'*6)

#字符串的转换  int(),float(),str()
 num1=3.6
 num1_1='3.6'
 print(int(num1))
 print(int(float(num1_1)))  #直接转'3.6'会报错,可以先转为float型的3.6,再转为int型

#转义符
 path1='d:\note1.txt'
 path1='d:\\note1.txt'  #再加一个\去掉转义符的特殊含义
 path1=r'd:\note1.txt'  #字符串前面加一个r,表示后面的字符串不进行转义
 path1='d:/note1.txt'  #路径可以使用/代替\

#字符串的下标
str6='nybtevrc'
 print(str6[5])
 print(str6[-3])
 str6[5]='c'  #报错,字符串是不可变对象

#字符串的切片  [起始值:终止值:步长]  包含起始值,不包含终止值,步长默认为1
#字符串的切片是生成了新对象,与原对象无关
 print(str6[3:6])
 print(str6[-5:-2])

 print(str6[5:2:-1])  #vet
 print(str6[-3:-6:-1])  #vet

#翻转字符串
 print(str6[::-1])

#列表可以存放哪些对象?任意对象
#列表是可变对象,可以增删改
#增  append,insert,extend
#改  通过下标就可以改
#删  pop,remove,del
#1,1,2,3,5,8,13,21,34  斐波那契数列
 list1=[]
 for i in range(20):
     if i<=1:
         list1.append(1)
     else:
         list1.append(list1[-2]+list1[-1])
 print(list1)

#列表的切片,也是生成一个新的对象,原理与字符串的切片一样
 print(list1[:])  #生成一个完整的切片,原列表的一个复制

#元组  元组也可以使用下标和切片,但是元组是不可变对象
 tuple1=(10,)  #元组中只有一个值时,后面加一个逗号
 print(type(tuple1))
 tuple2=(10,20,30)
 print(tuple2[:2])

#浅拷贝,深拷贝
list9=[10,20,30,[40,50]]
 list9_new=list9  #此处实际上只是建立了list9的一个快捷方式
 list9[0]=200
 print(list9)
 print(list9_new)

import copy
 list9_new=copy.copy(list9)  #浅拷贝 列表是不同的对象,子列表仍然是相同的对象
 list9[0]=200
 list9[-1][0]=360  #对子列表修改,两者仍然指向的是同一个子列表
 print(list9)
 print(list9_new)
#浅拷贝等价于切片list9_new=copy.copy(list9),也可以写成list9_new=list9[:]

 list9_new=copy.deepcopy(list9)  #深拷贝,列表和子列表都是不同的对象
 list9[-1][0]=360
 print(list9)
 print(list9_new)

#list()函数,将对象转为列表,tuple()函数,将对象转为元组

#布尔表达式
#and 一假为假,全真为真
#or  一真为真,全假为假
#210321_python知识点复习下
 import time
 for i in range(10,0,-1):
     print(f'\r倒计时{i}秒',end='')  #\r让光标回到行首
     time.sleep(1)  #让程序等1秒
 else:  #循环正常结束时,执行一次else中的语句
     print(f'\r倒计时结束')

 for i in range(1,11):
     if i==5:
         # break  #终止循环
         continue  #跳出一次循环
     else:
         print(i)

#使用while循环时,注意设置终止条件,如果while后面的布尔表达式始终为真,则会变为死循环
 i=0
 while i<=5:
     print('12345')
     i+=1

#文件读写
 with open('d:/210321.txt','w+') as file1:
     file1.write('庆历四年春,滕子京谪守巴陵郡.')
     file1.seek(0)
     print(file1.read())

#字典
#字典是可变对象
#字典的键可以存放不可变对象
#字典的值可以存放任何对象
#字典以键值对的形式进行存放
#字典是无序的
dict1={'A':'apple','B':'book'}
dict2={'B':'book','A':'apple'}
# print(dict1==dict2)

for k,v in dict1.items():
    print(k,v)

#json格式
str1='''{
    "aac003" : "tom",
    "tel" : "13959687639",
    "crm003" : "1",
    "crm004" : "1"
}'''
import json  #加载json模块
str1_new=json.loads(str1)  #loads()方法,将json格式转为真正的字典
# print(type(str1_new))
str2=json.dumps(str1_new)  #dumps()方法,将字典转为json格式
print(type(str2))
print(str2)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值