一、时间模块(time、datetime)
Python中有三种时间的表示方式:
- 时间戳 1970年1月1日之后的秒,即:time.time()
- 格式化时间 2014-11-11 11:11, 即:time.strftime('%Y-%m-%d')
- 结构化时间 元组包含了:年、日、星期等... time.struct_time 即:time.localtime()
1.1、几种时间表示方式的转换
#时间戳转结构化时间
import time
y=time.time() #时间戳
x=time.localtime(y) #时间戳转换结构化时间
#结构化时间转成时间戳
z=time.mktime(x) #结构化时间z转时间戳
time.gmtime() #世界标准时间(结构化时间)
#结构化时间转换为格式化时间
time.strftime(%Y-%m-%d-%b %H:%M:%S',x)) #可带参数指定结构化时间
time.strftime('%Y/%m/%d %H:%M:%S') #没有参数默认就是localtime
#格式化时间转换成结构化时间
time.strptime('2011-05-05 16:37:06', '%Y-%m-%d %X'))
#strptime(string, format)
# %Y %m %d %H %M %S %X %a %b
# 年 月 日 时 分 秒 时分秒统称 周 月
time.asctime()
#把一个表示时间的元组或者struct_time表示为这种形式:'Sun Jun 20 15:21:05 1998',如果没有参数,将会将time.localtime()作为参数传入
time.ctime()
#把一个时间戳(按秒计算的浮点数)转化为time.asctime()的形式。如果参数未给或者为None的时候,将会默认time.time()为参数
1.2、datetime模块
import datetime
print(datetime.datetime.now()) #返回格式 2018-12-16 17:12:41.621179
print(datetime.date.fromtimestamp(time.time()) )# 时间戳直接转成日期格式 2018-12-16
print(datetime.datetime.now() + datetime.timedelta(3)) #当前时间+3天
print(datetime.datetime.now() + datetime.timedelta(-3)) #当前时间-3天
print(datetime.datetime.now() + datetime.timedelta(hours=3)) #当前时间+3小时
print(datetime.datetime.now() + datetime.timedelta(minutes=30)) #当前时间+30分
print(datetime.datetime.now() + datetime.timedelta(seconds=30)) #当前时间+30秒
n_time = datetime.datetime.now()
print(n_time.replace(minute=3,hour=2)) #时间替换
执行结果:
二、random 随机模块
import random #随机模块
random.random() #0-1 浮点型
random.uniform(1,3) # 随机取1-3的浮点数
random.randint(1,4) #随机取1-4的整型
random.randrange(1,4) #随机取1-3的整数
random.choice([1,23,[22]]) #列表随机取一个值
print(random.sample([1,2,3],3)) #列表随机取多个值
list=[1,3,5,7,9]
random.shuffle(list) #随机打乱列表顺序
print(list)
chr(random.randint(65,90)) #随机大写字母A-Z
chr(random.randint(97,122)) #随机小写字母a-z
随机取4个值要求包含0-9,a-z,A-Z
import random
def code():
li = []
for i in range(1,5):
a=random.randint(0,9)
b=chr(random.randint(65,90))
c=chr(random.randint(97,122))
c=random.sample([a,b,c],1)
li.append(c)
return li
print(code())
其实上面这个例子并不严谨,0-9,a-z,A-Z各取一个,然后在从三个里面再任意取一个,把获取的四个值任意排序即可
三、OS模块
#当前工作目录相关的
os.getcwd() #获取当前工作目录,即当前python脚本工作的目录路径
os.chdir("dirname") #改变当前脚本工作目录;相当于shell下cd
os.curdir #返回当前目录: ('.')
os.pardir #获取当前目录的父目录字符串名:('..')
#和文件相关
os.makedirs('name1/name2') #可生成多层递归目录
os.removedirs('dirname') #删除多层目录,为空删除,否则报错
os.mkdir('dirname') #生成单级目录;相当于shell中mkdir dirname
os.rmdir('dirname') #删除单级空目录,若目录不为空则无法删除
os.listdir('dirname') #列出指定目录下的所有文件和子目录,包括隐藏文件
os.remove('filename') #删除一个文件
os.rename("oldname","newname") #重命名文件/目录
os.stat('path/filename') #获取文件/目录信息
# 和执行系统命令相关
os.system("bash command") #运行系统命令,直接显示
os.popen("bash command").read() #运行系统命令,获取执行结果
os.environ #获取系统环境变量
os.name() #字符串指示当前使用平台。win->'nt'; Linux->'posix'
#path系列,和路径相关
os.path.abspath(path) #返回path规范化的绝对路径
os.path.split(path)#将path分割成目录和文件名二元组返回
os.path.dirname(path) #返回path的目录。其实就是os.path.split(path)的第一个元素
os.path.basename(path) #返回path最后的文件名。如何path以/或\结尾,那么就会返回空值,即os.path.split(path)的第二个元素。
os.path.exists(path) #如果path存在,返回True;如果path不存在,返回False
os.path.isabs(path) #如果path是绝对路径,返回True
os.path.isfile(path) #如果path是一个存在的文件,返回True。否则返回False
os.path.isdir(path) #如果path是一个存在的目录,则返回True。否则返回False
os.path.join(path,*paths) #将多个路径组合后返回
os.path.getatime(path) #返回path所指向的文件或者目录的最后访问时间
os.path.getmtime(path) #返回path所指向的文件或者目录的最后修改时间
os.path.getsize(path) #返回path的大小
os.stat('path/filename') 获取文件/目录信息 的详细说明
st_mode: inode 保护模式 st_ino: inode 节点号。 st_dev: inode 驻留的设备。 st_nlink: inode 的链接数。 st_uid: 所有者的用户ID。 st_gid: 所有者的组ID。 st_size: 普通文件以字节为单位的大小;包含等待某些特殊文件的数据。 st_atime: 上次访问的时间。 st_mtime: 最后一次修改的时间。 st_ctime: 由操作系统报告的"ctime"。在某些系统上(如Unix)是最新的元数据更改的时间,在其它系统上(如Windows)是创建时间
OS模块中os.path.join()\basename()\split() 比较重要(对文件路径拼接、文件名操作等)
四、sys模块
sys.argv # 命令行参数,第一个元素是程序本身路径,后面为输入参数(list)
sys.exit() #退出程序,正常退出时exit(0)
sys.version #获取Python解释程序的版本信息
sys.maxint #最大的Int值
sys.path #返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform # 返回操作系统平台名称
sys.stdin #输入相关
sys.stdout #输出相关
sys.stderror #错误相关
sys.stdout.write("#") #输出"#"
sys.stdout.flush() #刷新缓存
五、数据转换相关(序列化)
5.1、josn 用于【字符串】和 【python基本数据类型】 间进行转换
josn模块提供了四个功能:dumps、dump、loads、load
#dumps和loads
import json
dic = {'k1':'v1','k2':'v2','k3':'v3'}
str_dic = json.dumps(dic) #序列化:将一个字典转换成一个字符串
print(type(str_dic),str_dic) #<class 'str'> {"k3": "v3", "k1": "v1", "k2": "v2"}
#注意,json转换完的字符串类型的字典中的字符串是由""表示的
dic2 = json.loads(str_dic) #反序列化:将一个字符串格式的字典转换成一个字典
#注意,要用json的loads功能处理的字符串类型的字典中的字符串必须由""表示
print(type(dic2),dic2) #<class 'dict'> {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
list_dic = [1,['a','b','c'],3,{'k1':'v1','k2':'v2'}]
str_dic = json.dumps(list_dic) #也可以处理嵌套的数据类型
print(type(str_dic),str_dic) #<class 'str'> [1, ["a", "b", "c"], 3, {"k1": "v1", "k2": "v2"}]
list_dic2 = json.loads(str_dic)
print(type(list_dic2),list_dic2) #<class 'list'> [1, ['a', 'b', 'c'], 3, {'k1': 'v1', 'k2': 'v2'}]
#dump和load
import json
f = open('json_file','w')
dic = {'k1':'v1','k2':'v2','k3':'v3'}
json.dump(dic,f) #dump方法接收一个文件句柄,直接将字典转换成json字符串写入文件
f.close()
f = open('json_file')
dic2 = json.load(f) #load方法接收一个文件句柄,直接将文件中的json字符串转换成数据结构返回
f.close()
print(type(dic2),dic2)
5.2、pickle 用于【python特有的类型】 和 【python基本数据类型】间进行转换
pickle模块提供了四个功能:dumps、loads、dump、load (不仅可以序列化字典,列表...可以把python中任意的数据类型序列化)
import pickle
dic = {'k1':'v1','k2':'v2','k3':'v3'}
str_dic = pickle.dumps(dic)
print(str_dic) #一串二进制内容
dic2 = pickle.loads(str_dic)
print(dic2) #字典
abc = {"k":1,"k1":2}
f = open('pickle_file','wb')
pickle.dump(abc,f)
f.close()
f = open('pickle_file','rb')
struct_time2 = pickle.load(f)
print(abc["k"])
5.3、shelve也是python提供给我们的序列化工具,比pickle用起来更简单一些。shelve只提供给我们一个open方法,是用key来访问的,使用起来和字典类似
import shelve
f1 = shelve.open('shelve_file')
f1['k1']={'name':'jump','age':18,'job':['php','smoking']} #写
print(f1['k1']['job']) #取 ['php', 'smoking']
f1.close()
5.4、XML是实现不同语言或程序之间进行数据交换的协议,XML文件格式如下:
<data>
<city name="bj">
<rank updated="yes">1</rank>
<year>2018</year>
<gdppc>141100</gdppc>
</city>
<city name="nj">
<rank updated="yes">5</rank>
<year>2018</year>
<gdppc>59900</gdppc>
</city>
<city name="sh">
<rank updated="yes">2</rank>
<year>2018</year>
<gdppc>13600</gdppc>
</city>
</data>
XML操作:
import xml.etree.ElementTree as ET
tree= ET.parse(filename) #解析文件
root=tree.getroot() #获取根节点
root.tag #根标签名称
for child in root:
print(child.tag, child.attrib) # 子节点的标签名称和标签属性
for i in child: #遍历XML文档的第三层
print(i.tag,i.text) # 二级节点的标签名称和内容
for i in root.iter("xxx"): #遍历根节点下面的所有xxx节点,然后修改
xx=int(i.text)+1
i.text=str(xx)
i.set("k",'v') #设置属性
del node.attrib['k'] #删除
tree.write("filename") #保存文件
for i in root.findall("city"):
xx = int(city.find("rank").text)
if xx>3:
root.remove(city) #删除排名大于3的
XML文件创建
import xml.etree.ElementTree as ET
new_xml=ET.Element("xxx") #创建根节点
name=ET.SubElement(new_xml,"name",attrib={"k":"v"}) #创建子节点
age=ET.SubElement(name,"age",attrib={"k1":"v1"}) #创建二级子节点
age.text = "22" #给节点定义值
et=ET.ElementTree(new_xml) #生成文档对象
et.write("abc.xml",encoding="utf8") #创建xml文件
六、文件及加密相关
6.1、configparser
configparser用于处理特定格式的文件,该模块适用于配置文件的格式与windows ini文件类似,可以包含一个或多个节(section),每个节可以有多个参数(键=值)
配置文件形式(mysql)
[client]
port = 3306
[mysqld]
port = 3306
datadir=D:\websoft\mysql-5.6.15\data
basedir=D:\websoft\mysql-5.6.15
max_connections=500
performance_schema=0
key_buffer = 16M
max_allowed_packet = 1M
#table_cache = 64
sort_buffer_size = 512K
net_buffer_length = 8K
read_buffer_size = 256K
read_rnd_buffer_size = 512K
myisam_sort_buffer_size = 8M
slow_query_log_file=D:\websoft\mysql-5.6.15\log\slow.log
创建一个配置文件:
import configparser
config= configparser.ConfigParser() #新建对象
config["Name"] ={'server':'hostname','IP':'111'} #Name节点下sever和IP
with open("config.conf","w")as f: #创建配置文件
config.write(f)
增删改查操作:
import configparser
config= configparser.ConfigParser()
config.read("config.conf") #打开配置文件
print(config.sections()) #获取所有的节点名称
print(config["Name"]["server"]) #获取Name节点下server的值
print(config.options("Name2")) #获取Name2节点下的键
print(config.items("Name")) #获取Name节点下所有的键值对
print(config.get("Name","server")) #获取Name 节点下server 的值
has_sec = config.has_section('section1')
print(has_sec) #判断是否包含section1这个节点,返回False/True
config.add_section("section1")
config.write(open('config.conf', 'w')) #增加一个节点section1
config.remove_section("section1")
config.write(open('config.conf', 'w')) #删除一个节点section1
config.set('section1', 'k10', "123")
config.write(open('config.conf', 'w')) #将section1节点下的k10设置为123
config.remove_option('section1', 'k10')
config.write(open('config.conf', 'w')) #将section1节点下的k10删除
config.has_option('section1', 'k10') #检查section节点下k10是否存在,返回False/True
6.2、shutil 高级的 文件、文件夹、压缩包 处理模块
import shutil
# shutil.copyfileobj(fsrc, fdst[, length]) 将文件内容拷贝到另一个文件中
shutil.copyfileobj(open('oldfilename','r'), open('newfilename', 'w'))
#shutil.copyfile(src, dst) 拷贝文件,目标文件无需存在
shutil.copyfile('f1', 'f2')
#shutil.copymode(src, dst)仅拷贝权限。内容、组、用户均不变
shutil.copymode('f1', 'f2') #目标文件必须存在
#shutil.copystat(src, dst)仅拷贝文件状态的信息
shutil.copystat('f1', 'f2') #目标文件必须存在
#shutil.copy2(src, dst) 拷贝文件和状态信息
shutil.copy2('f1', 'f2')
#shutil.copy(src, dst) 拷贝文件和权限
shutil.copy('f1', 'f2')
#shutil.ignore_patterns(*patterns)
#shutil.copytree(src, dst, symlinks=False, ignore=None)
#递归的去拷贝文件夹
shutil.copytree('dir1', 'dir2', ignore=shutil.ignore_patterns('*.txt'))
#目标目录不能存在,注意对dir2目录父级目录要有可写权限,ignore的意思是排除
#shutil.rmtree(path[, ignore_errors[, onerror]])
#递归的去删除文件夹
shutil.rmtree('dir1')
#shutil.move(src, dst)
#递归的去移动文件,它类似mv命令,其实就是重命名。
shutil.move('dir1', 'dir3')
#shutil.make_archive(base_name, format,...) 压缩文件
#base_name: 压缩包的文件名,也可以是压缩包的路径
#format:压缩包种类,“zip”, “tar”, “bztar”,“gztar”
#root_dir:要压缩的文件夹路径(默认当前目录)
shutil.make_archive("/bak/data_bak", 'zip', root_dir='/data')
#shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的,如下:
import zipfile
# 压缩
z = zipfile.ZipFile('bak.zip', 'w')
z.write('1.txt')
z.write('2.txt')
z.close()
# 解压
z = zipfile.ZipFile('bak.zip', 'r')
z.extractall(path='.')
z.close()
import tarfile
tar = tarfile.open('your.tar','w') # 创建一个压缩包
tar.add('/Users/bbs2.log', arcname='bbs2.log') # 将文件添加到压缩包并命名
tar.add('/Users/cmdb.log', arcname='cmdb.log')
tar.close() # 关闭压缩包
# 解压
tar = tarfile.open('your.tar','r') # 打开一个压缩包
tar.extractall() # 解压包内所有文件(可设置解压地址)
tar.close() # 关闭压缩包
6.3、hashlib
用于加密相关的操作,代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法
import hashlib
obj=hashlib.md5() #建立一个对象
obj.update("hello".encode("utf-8")) #加密
print(obj.hexdigest()) #5d41402abc4b2a76b9719d911017c592 (十六进制)
print(obj.digest)
以上加密算法虽然依然非常厉害,但时候存在缺陷,即:通过撞库可以反解。所以,有必要对加密算法中添加自定义key再来做加密。
import hashlib
obj=hashlib.md5("jump".encode("utf8")) #加自定义key
obj.update("hello".encode("utf-8"))
print(obj.hexdigest()) #b455addaf0e23904477ba8db951f3edc
七、 re 正则
正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法。或者说:正则就是用来描述一类事物的规则。(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行
元字符 | 匹配内容 |
\w | 匹配字母(包含中文)或数字或下划线 |
\W | 匹配非字母(包含中文)或数字或下划线 |
\s | 匹配任意的空白符 |
\S | 匹配任意非空白符 |
\d | 匹配数字 |
\D | 匹配非数字 |
\A | 从字符串开头匹配 |
\z | 匹配字符串的结束,如果是换行,只匹配到换行前的结果 |
\Z | 匹配字符串的结束 |
\n | 匹配一个换行符 |
\t | 匹配一个制表符 |
^ | 匹配字符串的开始 |
$ | 匹配字符串的结尾 |
. | 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。 |
[...] | 匹配字符组中的字符 |
[^...] | 匹配除了字符组中的字符的所有字符 |
* | 匹配0个或者多个左边的字符。 |
+ | 匹配一个或者多个左边的字符。 |
? | 匹配0个或者1个左边的字符,非贪婪方式。 |
{n} | 精准匹配n个前面的表达式。 |
{n,m} | 匹配n到m次由前面的正则表达式定义的片段,贪婪方式 |
a|b | 匹配a或者b。 |
() | 匹配括号内的表达式,也表示一个组 |
7.1、常用方法举例
import re
#findall 全部找到返回一个列表
#findall(pattern, string, flags=0)
print(re.findall("a","abcdabcdaa")) #['a', 'a', 'a', 'a']
#search 只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。
# search(pattern, string, flags=0)
print(re.search("a","abcdabcdaa").group()) #a
print(re.search("a","abcdabcdaa")) #<_sre.SRE_Match object; span=(0, 1), match='a'>
#match 同search,不过在字符串开始处进行匹配,完全可以用search+^代替match
#match(pattern, string, flags=0)
# pattern: 正则模型
# string : 要匹配的字符串
# falgs : 匹配模式
print(re.match('e','ebcdh').group()) #e
print(re.match('e','ebcdh')) #<_sre.SRE_Match object; span=(0, 1), match='e'>
#split 分割 可按照任意分割符进行分割
#split(pattern, string, maxsplit=0, flags=0)
# pattern: 正则模型
# string : 要匹配的字符串
# maxsplit:指定分割个数
# flags : 匹配模式
print(re.split('[ab]','abcd')) #['', '', 'cd'],先按'a'分割得到''和'bcd',再对''和'bcd'分别按'b'分割
#sub 替换
#sub(pattern, repl, string, count=0, flags=0)
# pattern: 正则模型
# repl : 要替换的字符串或可执行对象
# string : 要匹配的字符串
# count : 指定匹配个数
# flags : 匹配模式
r = re.sub("\d+", "999", "123abcd456edcf789", 2)
print(r) #999abcd999edcf789
#re.compile()
obj = re.compile("\d+")
print(obj.search("abcd123efg456yhn789").group())
print(obj.findall("abcd123efg456yhn789"))
#返回123 和['123', '456', '789']
7.2、命名分组
print(re.search("(?P<tag_name>\w+)","abcd"))
#(?P<name>) 分组固定格式
print((re.search("(?P<tag_name>\w+)","abcd").group("tag_name")))
#取分组值
print(re.search("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>","<h1>hello</h1>").group())
print(re.findall("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>","<h1>hello</h1>"))
#返回的结果为:<h1>hello</h1>和[h1]
#group的作用是将所有组拼接到一起显示出来
#findall结果是组内的结果,且是最后一个组的结果
八、logging 用于便捷记录日志且线程安全的模块(日志模块)
日志等级:
CRITICAL = 50 #FATAL = CRITICAL
ERROR = 40
WARNING = 30 #WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0 #不设置
import logging
logging.debug('调试debug')
logging.info('消息info')
logging.warning('警告warn')
logging.error('错误error')
logging.critical('严重critical')
#返回结果:
"""WARNING:root:警告warn
ERROR:root:错误error
CRITICAL:root:严重critical"""
#默认级别为warning,默认打印到终端
8.1、单文件日志
import logging
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
datefmt='%a, %d %b %Y %H:%M:%S',
filename='1.log',
filemode='w')
logging.debug('debug message')
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message')
执行结果:
相关参数详情:
logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有:
filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中。
filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
format:指定handler使用的日志显示格式。
datefmt:指定日期时间格式。
level:设置rootlogger(后边会讲解具体概念)的日志级别
stream:用指定的stream创建StreamHandler。
可以指定输出到sys.stderr,sys.stdout或者文件(f=open(‘test.log’,’w’)),默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。
logging.StreamHandler() #打印到桌面
format参数中可能用到的格式化串:
%(name)s Logger的名字
%(levelno)s 数字形式的日志级别
%(levelname)s 文本形式的日志级别
%(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
%(filename)s 调用日志输出函数的模块的文件名
%(module)s 调用日志输出函数的模块名
%(funcName)s 调用日志输出函数的函数名
%(lineno)d 调用日志输出函数的语句所在的代码行
%(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
%(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
%(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
%(thread)d 线程ID。可能没有
%(threadName)s 线程名。可能没有
%(process)d 进程ID。可能没有
%(message)s用户输出的消息
8.2、多文件日志
import logging
#定义正确输出日志
run_log = logging.FileHandler('run.log', 'a', encoding='utf-8')
fmt = logging.Formatter(fmt="%(asctime)s - %(levelname)s : %(message)s")
run_log.setFormatter(fmt)
logger_info = logging.Logger('run_log', level=logging.INFO)
logger_info.addHandler(run_log)
#定义错误输出日志
error_log = logging.FileHandler('error.log', 'a', encoding='utf-8')
fmt = fmt = logging.Formatter(fmt="%(asctime)s - %(levelname)s : %(message)s")
error_log.setFormatter(fmt)
logger_error = logging.Logger('error_log', level=logging.ERROR)
logger_error.addHandler(error_log)
logger_info.info("xxx")
logger_error.error("yyy")
执行结果:
这样在后续的使用中我们可以通过定义函数(或者类)来按需调用 即可
#logger:产生日志的对象
#Filter:过滤日志的对象
#Handler:接收日志然后控制打印到不同的地方,FileHandler用来打印到文件中,StreamHandler用来打印到终端
#Formatter对象:可以定制不同的日志格式对象,然后绑定给不同的Handler对象使用,以此来控制不同的Handler的日志格式
#Handler对象:接收logger传来的日志,然后控制输出
run_log = logging.FileHandler('run.log', 'a', encoding='utf-8')
#Formatter对象:日志格式
fmt = logging.Formatter(fmt="%(asctime)s - %(levelname)s : %(message)s")
#为Handler对象绑定格式
run_log.setFormatter(fmt)
#logger对象:负责产生日志,然后交给Filter过滤,然后交给不同的Handler输出
logger_info = logging.Logger('run_log', level=logging.INFO)
#将Handler添加给logger
logger_info.addHandler(run_log)
九、补充
9.1、paramiko 模块
paramiko是一个用于做远程控制的模块,使用该模块可以对远程服务器进行命令或文件操作,值得一说的是,fabric和ansible内部的远程管理就是使用的paramiko来现实的。
#下载安装
#pycrypto,由于 paramiko 模块内部依赖pycrypto,所以先下载安装pycrypto
pip3 install pycrypto
pip3 install paramiko
#执行命令打印结果
# 用户名密码方式
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('192.168.1.50', 22, 'root', '1234')
stdin, stdout, stderr = ssh.exec_command('df')
print (stdout.read())
ssh.close()
#秘钥方式
private_key_path = '/home/auto/.ssh/id_rsa'
key = paramiko.RSAKey.from_private_key_file(private_key_path)
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('主机名 ', 端口, '用户名', key)
stdin, stdout, stderr = ssh.exec_command('df')
print (stdout.read())
ssh.close()
#上传下载文件
#用户名、密码方式
import os,sys
import paramiko
t = paramiko.Transport(('192.168.1.50',22))
t.connect(username='root',password='123')
sftp.put('test.py','/test.py') #上传
sftp.get('/test.py','/test2.py') #下载
t.close()
#秘钥方式
pravie_key_path = '/home/auto/.ssh/id_rsa'
key = paramiko.RSAKey.from_private_key_file(pravie_key_path)
t = paramiko.Transport(('192.168.1.50',22))
t.connect(username='root',pkey=key)
sftp = paramiko.SFTPClient.from_transport(t)
sftp.put('test3.py','/tmp/test3.py') #上传
sftp.get('/tmp/test3.py','/test4.py') #下载
t.close()
9.2、Requests模块 是使用 Apache2 Licensed 许可证的 基于Python开发的HTTP 库,其在Python内置模块的基础上进行了高度的封装,从而使得进行网络请求时,变得美好了许多,使用Requests可以轻而易举的完成浏览器可有的任何操作。(ython标准库中提供了:urllib等模块以供Http请求,但是,它的 API 太渣了)
#安装模块
pip3 install requests
# 1、无参数实例
import requests
ret = requests.get('https://www.baidu.com')
print(ret.url)
# 2、有参数实例
payload = {'key1': 'value1', 'key2': 'value2'}
ret = requests.get("http://www.baidu.com", params=payload)
print(ret.url)
#返回结果
#https://www.baidu.com/
#http://www.baidu.com/?key1=value1&key2=value2
# 1、基本POST提交
import requests
data = {'key1': 'value1', 'key2': 'value2'}
ret = requests.post("http://www.baidu.com", data=payload)
print(ret.text)
# 2、发送请求头和数据
import json
url = 'https://www.baidu.com'
data = {'k': 'v'}
headers = {'content-type': 'application/json'}
ret = requests.post(url, data=json.dumps(data), headers=headers)
实例:1、查看火车停靠信息及时间 2、查看城市的天气预报
#1、查看去上海的G7021号火车的停靠信息及时间
r = requests.get('http://www.webxml.com.cn/WebServices/TrainTimeWebService.asmx/getDetailInfoByTrainCode?TrainCode=G7021&UserID=')
result = r.text
# 解析XML格式内容
root = ET.XML(result)
for node in root.iter('TrainDetailInfo'):
print(node.find('TrainStation').text,node.find("ArriveTime").text,node.find("StartTime").text)
#2、查看上海的天气预报
r = requests.get('http://ws.webxml.com.cn/WebServices/WeatherWS.asmx/getWeather?theCityCode=上海&theUserID=')
result = r.text
# 解析XML格式内容
root=ET.XML(result)
for node in root:
print(node.text)
执行结果:
Ps:更多接口可以查看 http://www.webxml.com.cn/zh_cn/web_services.aspx
9.3、suprocess 模块用于执行系统相关命令返回结果
#call 执行命令,返回状态码
ret = subprocess.call(["ls", "-l"], shell=False)
ret = subprocess.call("ls -l", shell=True)
#check_call执行命令,如果执行状态码是 0 ,则返回0,否则抛异常
subprocess.check_call(["ls", "-l"])
subprocess.check_call("exit 1", shell=True)
#check_output执行命令,如果状态码是 0 ,则返回执行结果,否则抛异常
subprocess.check_output(["echo", "Hello World!"])
subprocess.check_output("exit 1", shell=True)
#subprocess.Popen(...) 用于执行复杂的系统命令
obj = subprocess.Popen('dir',
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
print(obj.stdout.read().decode('utf-8')) # 正确命令
print(obj.stderr.read().decode('utf-8')) # 错误命令
# shell: 命令解释器,相当于调用cmd 执行指定的命令
# stdout:正确结果丢到管道中。
# stderr:错了丢到另一个管道中
subprocess.Popen()参数说明:
- args:shell命令,可以是字符串或者序列类型(如:list,元组)
- bufsize:指定缓冲。0 无缓冲,1 行缓冲,其他 缓冲区大小,负值 系统缓冲
- stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
- preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用
- close_sfs:在windows平台下,如果close_fds被设置为True,则新创建的子进程将不会继承父进程的输入、输出、错误管道。
所以不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。 - shell:同上
- cwd:用于设置子进程的当前目录
- env:用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。
- universal_newlines:不同系统的换行符不同,True -> 同意使用 \n
- startupinfo与createionflags只在windows下有效
将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等