# -*- coding: utf-8 -*-
# __author__:zhangpeng
# 2021-03-21
#1----字符串列表元组
#字符串拼接+:看前面的对象,先入为主(前面是字符串,后面就只能拼字符串),重复直接*n
#字符串长度len
#字符串序列1:有正负下标
#切片:分割字符串---获取某段字符串
#被切对象不发生改变
#info='abcdef'
#1-获取中间一段:切2次---3段
#print(info[1:1+2])#左含又不含
# print(info[1:])
# #2-获取前半段--取前值写后下标
# print(info[:3])
# #3-获取后半段-取后值
# # 写前下标
# print(info[3:])
# print(info[0:5:2])#[第一次切:第二次切:步长]
# #扩展
#print(info[::1])#源字符串
#print(info[::-1])#反序
#列表定义----也算是一种序列类型1:下标2:切片
#3-存储任意类型
# alist=[10,3.14,'hello',[100,200]]
# #切片操作
#print(alist[:1])#[10]
# print(alist[:2])#[10, 3.14]
#print(100 in alist[-1])
# alist=[10,20,30,40,50,10]
#列表查看
#print(alist[-1])
#列表修改
# alist[0]=50
# print(alist)
#列表增加--列表名.append
# alist.append(60)
# print(alist)
#插入值---列表名.insert(你需要的位置下标,插入的值)
# alist.insert(0,50)
# print(alist)
#列表删除---del--使用下标删除
#获取下标
# print(alist.index(10))
# del alist[1],alist[2]
# print(alist)
# del alist[1:1+2]
# print(alist)
#pop删除有返回值
# print(alist.pop(0))
# print(alist)
#remove删除(值)----效率最低
# alist.remove(10)
# print(alist)
#删除重复的元素
# while 10 in alist:
# alist.remove(10)
# print(alist)
#合并列表
#print(alist+[100,200])#另存地址
#2-alist.extend
# alist.extend([12,13])
# print(alist)#改变原数据[10, 20, 30, 40, 50, 10, 12, 13]
#元组--是序列类型
#元组不能改变:1、元素值不能变2、元素个数不能改变
#元组一般只支持查询,只读---系统配置参数
# tul=(10,)
# alist=[10,20,10,30,10]
# while 10 in alist:
# del alist[alist.index(10)]
# print(alist)
#2---布尔类型
#数值比较,关系运算符> < == !=
#== 表示值/内容相等,是否同一个对象》---id()--is
# print(3!=1)
#字符串比较:对应位置的字符的ascii值大小,a 97 A 65
# print('abc'>'bc')
#in---列表:1、前者是后者的一个元素
# alist=[10,20,30,[100,200]]
# print(10,20 in alist)
#1--逻辑且--and---一假为假,全真为真
#2--逻辑或---or----一真为真,全假为假
#3---逻辑不--not-----取反
#4----优先级---关系运算符>逻辑运算符 not>and>or
#赋值----指向,引用操作
#alist=[10,20,30,[100,20]]
#浅拷贝----两层列表---可以拷贝出来父级列表
# --这个父级列表跟源数据不是同一个---但子列表还是同一个对象
#深拷贝----彻底的拷贝---内外层列表都独立,不是同一个对象-列表里面还嵌套列表就用深拷贝-
#3---条件判断---if 、if--else、if---elif
#单个if语句---使用场景:只需要对条件满足的处理就可以
#if--else-使用场景:处理条件的对立面,满足其一,另外的条件不执行
#多分支if--elif-使用场景:>2多种选择
#if 嵌套---分层条件
# score=85
# if score>=60:
# if score>=80:
# print('A')
#复合条件--if age=60 and gemder='male'
#扩展
#1-if-后面只要是非零数值、非空字符串、非空列表就是为真
#2-控制台输出print 输入input
# score=int(input('请输入分数:'))
# print(score+5)
#4---函数
#往后缩进tab,往前缩进 shift+tab
# def f1():#函数定义---不内部执行代码
# print('你吃饭了没有')
# f1()#函数调用--执行内部代码
#函数参数:形参、实参
# def get_sum(a,b):#函数定义的参数--形参
# print(a+b)
# get_sum(1,2)#函数实际调用传入的参数----实参
# get_sum(a=1,b=2)
# get_sum(a=1,2)#调用错误,函数调用的时候,如果出现了实参是变量=值的写法,后面的参数要保持这个队形写法
#函数返回值:函数运行完成后,会有一个对象(值)返回
#使用场景:A同时定义了一个函数get_sum(a,b)
#B同事想调用A函数,获得的结果再加上10
# def get_sum(a,b):
# return a+b#函数的结束
# res=get_sum(1,2)+10
# print(res)
# print(get_sum(1,2)+10)#函数有多个返回值,返回的结果是元组
#内置函数:print/len/max/min/type/input
#类型转换:str()---把其他类型转为字符串
#int()---把字符串转为int--正负整数数值
#float()---对其他类型转换成float
#list()------转换成列表
#tuple()----转换成元组
# a=[100,200]
# b=str(a)
# print(type(b),b,len(b))
#5----对象的方法
#对象方法实际就是类里面定义的函数
#函数没有返回值---None
a='babc'
# print(a.count('a'))#count计数
# print(a.endswith('c'))#---返回布尔值:endswith以什么结尾
# print(a.startswith('c'))#---返回布尔值:startswith以什么开头
#find--查找
#如果元素存在返回第一个字符出现的下标
#如果元素不存在---返回-1
# print(a.find('a'))
#index()--求下标--这个元素一定要有才行,元素不存在直接报错
#isalpha---检查字符串中是否都是字母
#Isdigit---检查字符串中是否都是数字
#jion---将字符串拼接
# print('****'.join(['name','is','bob']))
#split---分割,返回的是列表
# str='abadea'
# print(str.split('a'))#返回是列表---切点会被切掉
#replace--替换:默认全部替换,后面加个数可以指定替换几个('a','x',个数)
#strip---去掉开头和结尾的空格,不能去掉中间的空格
#6----字符串格式化
#字符串格式:往字符串里面传递参数,也就是表达一个字符串
#格式化方法1---%占位法,%s代表字符串传入,%d代表十进制传入
# name='tom'
# age=20
# info='我叫%s,年龄是%s' %(name,age)
# print(info)
#print('%05d' %56)#%5d 元素的长度为5个,%正数值d,右对齐,左补齐,补空格
# print('%-5d' %56)#%-5d 元素的长度为5个,%负数值d,左对齐,右补齐,补空格
# print('%f' %3.145674567)#默认6位---超过6为会四舍五入
# print('%7.3f'%3.145674567)#---会四舍五入
#注意事项:如果长度要求<传入只本身长度,不理会该要求
#2--格式化2--字符串.format
#顺序填坑--一个萝卜一个坑---指定宽度{:方向宽度}---<左对齐,>右对齐,^居中对齐
#补齐元素请在{:补齐元素>6}
# info='我叫:{:*>6},年龄是{:0>6}'.format(name,age)
# print(info)
#下标填值法
# info='我叫:{0:*>6},年龄是{1:*>6}'.format(name,age)
# print(info)
#python3.6方法之后可以用f方法,对齐与format一致
# info=f'我叫:{{name}},年龄是{age}'
# print(info)
#7----循环语句之while
# while 3>2:
# print('我在循环了')
# print('运行结束')
#求1-100的和
'''
功能需求:
1-基本的求和---while
2-想经常使用---使用函数--定义行数 def
3-想获取运算的结果和---加返回值 return
4-函数的调用想算自定义的和---增加接口概念---形参
5-求指定范围内的奇数/偶数的和
6-求等差数列的和
7-增加缺省参数
'''
# def get_sum(start,end,step=1):#函数定义 变量=值,缺省参数
# '''
# :param start:
# :param end:
# :param step:
# :return:
# '''
# sumDate=0
# cnt=start#从1开始累加
# while cnt<=end:
# #不断在累加
# sumDate+=cnt
# cnt+=step#自变量加1
# return sumDate
# print(get_sum(1,10,2))#求奇数和
# print('运行结束')
#7----循环语句之for遍历操作
# students=['mike','jack','mary']
# for name in students:
# print(name)
# for one in range(5,0,-1):#左含又不含
# print(one)
'''
while使用场景:
1-根据条件结束
2-while True:if break :#当一个场景不知道循环次数,但是循环是通过条件结束
for使用场景:
1-遍历操作
2-需要指定循环次数
'''
#循环语句之break中止循环
# for one in range(1,5):
# if one==3:
# break#中止,结束本层循环
# #continue#继续,结束本次循环,继续下次循环
# print(one)
# print(print.__doc__)#函数.__doc__api说明
#8文件操作--主要针对文本文件,不包括excel
#1-文件路径
#fileDir='G:/pyTest.txt'
# fileDir2='D:\\pyTest.txt'
# #fileDir3=r'G:\pyTest.txt'#r 取消转义
# fo=open(fileDir2)
#2-读操作--如果文件不存在---会报错
# print(fo.tell())
# print(fo.read(2))#返回的是字符串
# print(fo.tell())
#文件指针移到,seek
#0模式--永远从文件指针开始地方计算0
# fo.seek(1,0)#(移动到的位置,模式)
# print('seek操作后----',fo.tell())
# fo.seek(1,1)#二进制模式
#读取一行
#print(fo.readline())
#读取多行--返回的list列表
# print(fo.readlines())
# print(fo.read().splitlines())
#文件关闭
# fo.close()
#2-文件写操作----如果文件不存在--会新建;文件存在--会清空所有内容
#使用场景:输出本次使用的详细信息
#fileDir2='D:\\pyTest.txt'
# fo=open(fileDir2,'a')#w--写 a---追加
# #写操作
# fo.write('\n12314')#本质是不写磁盘,写在缓存里
# fo.flush()#刷新到磁盘
#3-如果需要打开多个文件操作
#优势:可以省掉close()操作
#with open(fileDir2) as fo,open('xx')as fo2:
#9---循环嵌套
# boys=['mark','jack','tom']
# girls=['lisa','linda','marry']
# for girl in girls:
# for boy in boys:
# print(girl,boy)
#列表生成式--一般用于比较简单的列表处理
#不好调试
# befortax=[10000,15000,8000,4000,5000]
# aftertax=[int(one*0.9)for one in befortax if one>=5000]
# print(aftertax)
# alist=[9,2,6,0]
# alist.sort(reverse=True)#降序
# print(alist)
# print(alist[::-1])#升序
#冒泡排序--升序
#找n-1较大值,两两相邻元素对比,大的往后移
# alist=[9,2,6,0]
'''排序思路:找出4-1=3较大值--for循环 n-1
1-第一个较大值---9
1-[9,2,6,0]---9与2比较--9大--9与2交换位置[2,9,6,0]
2-[9,2,6,0]---9与6比较--9大--9与6交换位置[2,6,9,0]
3-[9,2,6,0]---9与0比较--9大--9与0交换位置[2,6,0,9]
2-第二个较大值---6
2-第三个较大值---2
'''
#1-需要找n-1较大值
# for i in range(0,len(alist)-1):
# #2-每一次较大值怎么找--相邻比较
# for j in range(0,len(alist)-1-i):
# if alist[j]>alist[j+1]:
# alist[j],alist[j+1]=alist[j+1],alist[j]
# print(alist)
#交换数据例子
# a=10
# b=20
# a,b=b,a
# print(a,b)
#------字典------
#字典定义
#dict1={}
'''
字典定义与特性:
1-键值成对出现
2-键的类型:可以是字符串、int、float、元组---不可以改变的类型
不可以的是:列表、字典
3-字典可以改变只
4-没有顺序-就没有下标-不像列表
5-键永远是唯一的
'''
dict1={"name":"tom","age":{"info":"15"}}
#字典的for循环本质是对键操作
# for one in dict1:
# print(one)
# for one in dict1.items():
# # print(one)
# for a,b in dict1.items():
# print(a,b)
#获取值操作
# print(dict1["name"])
# print(dict1["age"]["info"])
#字典修改值--通过键修改---键是存在
# dict1['name']='zhangpeng'
# print(dict1['name'])
#新增键值对:键不存在---不会报错
# dict1['aaa']='年龄'
# print(dict1)
#判断键存不存在---in----bool布尔
# print('aaa'in dict1)
#删除---没有remove
# del dict1['aaa']
# dict1.pop('name')
# print(dict1)
#查看字典的元素个数---求的是键值对个数
# print(len(dict1))
#清空
# dict1.clear()
# print(dict1)
#获取字典的所有值---类列表1、不支持下标操作2、支持遍历for
#可以强制转换类型
# print(list(dict1.keys()))
# for one in dict1.keys():
# print(one)
#获取所有值
# print('年龄' in dict1.values())
#获取键值对
# print(dict1.items())
#字典的合并update
#---扩展---
#json---一个格式"{"key":"vaa"}"
#dict---数据类型
# import json
# json.dumps()---字典转成json
# json.loads()----json转成字典(转源数据类型)
#------函数的深层次应用--------
#全局变量:在.py模块里,只要我们定义过这个变量,这行开始,后面的代码都可以使用
# x=2
# def func():
# #局部变量:在函数里面,定义的变量,出了函数就不能使用
# global x#如果要改全部变量,需要先用global声明
# x=9
# print("this x is in the func:---->1",x)#----9
# func()
# print("-----------------------")
# print("this x is out of func:---->2",x)#---2
#1-缺省参数:让函数调用更加便捷
# def get_sum(start=1,end=100):#用户不输入实参---默认值,用户输入就按用户输入的实际值传入
# sumDate=0
# i=start#从1开始累加
# while i<=end:
# #不断在累加
# sumDate+=i
# i+=1#自变量加1
# return sumDate
# print(get_sum())
# def func(a,b=1):#函数定义的时候,必填参数要在缺省参数前面
# print(a,b)
#2-可变数量参数-----(数量可以是0,也可以是n)---函数定义的时候 *变量名
#*可变数量参数--会封装成元组
# def func(a,*args,b=2):
# print(a,args,b)
# func(10,20,30,b=30)
# def func(*args):
# print(args)
# func(*[1,2,4])#函数调用的时候---*展开元素
#关键字参数
# def func(**kwargs):#**封装成字典
# print(kwargs)#---打印{}
# func(name="tom")#函数传值的时候一定要键值格式,格式:变量名=值
# func(**{'age':'30'})#在函数调用的时候,需要传入字典**展开成格式变量名=值
#---函数练习题综合使用----
# def func(a,b,c=0,*args,**kw):
# print(a,b,c,args,kw)
# func(1,2)#-------a=1,b=2,c=0,args=(),kw={}
# func(1,2,c=3)#-----a=1,b=2,c=3,args=(),kw={}
# #func(1,2,c=3,5)#-----会报错,缺省参数后面必须要跟前面的保持队形x=5
# func(1,2,c=3,r=5)#-----a=1,b=2,c=3,args=(),kw={'r': 5}
# func(1,2,3,'a','b')#----a=1,b=2,c=3,args=('a', 'b'),kw={}
# func(1,2,3,'a','b',x=99)#----a=1,b=2,c=3,args=('a', 'b'),kw={'x': 99}
#-----模块与包----------------------
#一个.py文件就称之为模块,存放模块文件的目录称之为包,模块不可以与第三方库名称相同
#导入模块--import模块名---一般以模块作为最小单元
#同一个包怎么调用-----模块名.函数
#不同包怎么调用--------import 包名.模块名(as mt)---包名太长可以用as重新命名
#导入多个模块---import 模块1,模块2
#from import----比较针对性---导入什么只用什么---直接导入函数、变量、类
#同包---from 模块名 import 函数名
#不同包---from 包名.模块名 import 函数名
# if __name__ == '__main__':#模块代码调试
# xx
#程序人口
#1-如果运行当前模块,这个__name__ == '__main__'主模块
#2-如果一个模块被调用--__name__=模块名
# class T:
# # # name='xx'
#---py工具使用技巧---
#查看有多少类和函数---view--toolwindows-- structure
#查看那个模块用了函数find_usages
#改目录名---rename
#分屏--水平--alt+h,垂直--alt+v
#settings中的keymap自定义快捷键
#shfit+enter--任意位置换行
# from zhansan import hanshu
# hanshu.get_sum()
#----代码调试----
#step over--f8:一行作为一步全速运行
#step into---f7:跳入函数或者方法里面
#完美打印pprint---接口返回数据专用
# def func():
# print('test01')
# print('test02')
# print('test03')
#
#
# func()
#---类-----
# class Tiger:
# #1-静态属性:这个特征属于整个类所有的实例---大家一样的特征
# nickName='Tiger'
# #2-实例属性--大家有些特征不一样---每一个实例的特征可以不一样
# def __init__(self,inweight):
# #print(self,'-----我被执行了-----',inweight)#初始化方法---只要创建实例,这个方法就会自动调用
# self.weight=inweight
# #创建实例
# t1=Tiger(100)
# print(t1.nickName)#静态属性调用:1、实例.属性2、类.属性
# print(t1.weight)
# t2=Tiger(200)
# print(t2.weight)
# class Tiger:
# nickName = 'Tiger'
# #实例属性
# def __init__(self, inweight):
# self.weight = inweight
# #实例方法--叫
# def roar(self):
# print('我是老虎---wow')
# #体重减少5斤
# self.weight-=5
# # 实例方法--喂食
# def feed(self,food):
# if food=='肉':
# self.weight+=10
# print('恭喜,喂食正常,体重增加10斤')
# else:
# self.weight -= 10
# print('恭喜,喂食错误,体重减少10斤')
# #静态方法---所有的实例都一样的操作
# @staticmethod
# def static_roar():
# print('静态方法---wow')
# t1=Tiger(200)
# # print(f'操作前的体重:{t1.weight}')
# # t1.roar()
# # t1.feed('肉')
# # print(f'操作后的体重:{t1.weight}')
# # t1.static_roar()
# class sourthTiger(Tiger):#类的继承---节省重复代码量
# age=20
# def __init__(self,inName):
# Tiger.__init__(self,inweight=200)#手动调用父类的实例属性
# self.name=inName
# s1=sourthTiger('华南虎')
# print(s1.age)
#
# class Room:
# def __init__(self,inNum,inAnimal):
# self.num=inNum
# self.animal=inAnimal
#
# r=Room(2,t1)
# r.animal.feed('肉')
#----异常信息处理----
#if 过滤:事前处理:都是已知出现的情况
#异常处理:属于事后处理--报错后不停止,可以有适当提示
#使用场景:
#1-文件读操作:log txt--文件不存在--会直接报错
#2-小张:boss布置了web ui自动化的用例测试:10个用例,其中会有一个报错会导致后面的用例不能运行
#函数调用:从上往下调用的--公告的公布
#异常的抛出:从下往上---事故上报
# if xxx:#简单粗暴处理异常
# xxx
# import traceback
# while True:
# num=input('请输入一个值:')
# try:
# print('100/%s=%s'%(num,100/int(num)))
# # except ZeroDivisionError:#捕获一种异常--已知
# # print('请不要输入0,重新输入')
# # except ValueError as err:#捕获多种异常--已知
# # print('请输入数值!',err)
# except :
# print('异常了!统一方式处理',traceback.format_exc())
# else:
# print('没有异常执行')
# finally:
# print('最后一定要执行的代码')
# class NameTooLongErro(Exception):#自定义异常
# err='name.long'
# print('NameTooLongErro')
# def methFun(self):
# name=input('请输入用户名')
# if len(name)>10:
# raise NameTooLongErro#自定义异常要自行抛出
# else:
# raise xxx
# print(NameTooLongErro.err)
#----正则表达式----处理动态的字符串更强大
#表达式--匹配、切割、替换、获取
import re
#1-通配符.不包括\n换行符
# res=re.findall('s.','songqinsis')#需要2个必填参数(正则的表达式,处理的字符串)2、返回类型:列表
# print(res)
#2-*出现0次或者多次
res=re.findall('son*','songqinso')#需要2个必填参数(正则的表达式,处理的字符串)2、返回类型:列表
print(res)
#3-+出现一次或者多次
# res=re.findall('s+','songqinsin')#需要2个必填参数(正则的表达式,处理的字符串)2、返回类型:列表
# print(res)
# res=re.findall('son*','songqinso')#需要2个必填参数(正则的表达式,处理的字符串)2、返回类型:列表
# res1=re.findall('son+','songqinso')
# print(res)
# print(res1)
#4-?常用方法(.+?)(.*?)
#5-\w匹配所有的字母、数字、下划线 表示一个元素
# res=re.findall('\w{3}','songqin##123#45')
# print(res)
#6-\W匹配所有的非字母、数字、下划线 表示一个元素
# res=re.findll('\W{2}','songqin##123#45')
# print(res)
#7-\d匹配所有的数字[0-9]
# res=re.findall('\d{3}','songqin##123#45')
# print(res)
#8-compile --生成一个re对象--使用场景:这个re表达式用的地方很多
# obj=re.compile('\d{3}')
# print(obj.findall('songqin##123#45'))
#8-re.I--忽略大小写
# res=re.findall('s.','songqinSos\n',re.I|re.S)
# print(res)
#----爬虫实战----
#网络爬虫--爬取数据
#流程:模拟浏览器发送请求----下载网页代码---只提取有用的数据---存放与数据库或文件中
#---存储初始化--
import xlwt
#创建一个excel文件
workBook=xlwt.Workbook(encoding='utf-8')
#在文件对象创建一个sheet
workSheet=workBook.add_sheet('51job.res')
workBook.save('D:\\51job.xls')#存放路径
colName=['职位名','公司名','工作地点','薪资','发布时间']
for col in range(0,len(colName)):
workSheet.write(0,col,colName[col])#(行,列,内容)
#1-模拟浏览器发送请求
import requests
import re
web_url='http:www.baidu.com'
resp=requests.get(web_url)
resp.encoding='gbk'
print(resp.text)
print(resp.request.headers)#获取请求头
#2-解析页面内容
resp.encoding='gbk'
print(resp.text)
print(resp.request.headers)#获取请求头
#3-提取有用数据-re.s将字符串做为一个整体
info=re.findall('',resp.text,re.S)
for one in info:
temp=re.findall('',one,re.S)
#4-存储数据
#写进去excel
workSheet.write()
workBook.save('D:\\51job.xls')#存放路径