python day 9: xlm模块,configparser模块,subprocess模块
程序员文章站
2022-07-02 12:48:07
python day 9 2019/10/12 学习资料来自老男孩教育 [TOC] 1. xml模块 xml模块是在json没有出来之前,用于不同语言之间通信,交换,处理xml格式数据的一种方式。 1.1 初识xml 1.2 遍历xml文档的指定节点 创建一个xml文档,写入如下内容: 读取xml文 ......
目录
python day 9
2019/10/12
学习资料来自老男孩教育
1. xml模块
xml模块是在json没有出来之前,用于不同语言之间通信,交换,处理xml格式数据的一种方式。
1.1 初识xml
import requests from xml.etree import elementtree as et # 使用第三方模块requests发送http请求,或者xml格式内容 response = requests.get('http://www.webxml.com.cn//webservices/qqonlinewebservice.asmx/qqcheckonline?qqcode=375132083') result = response.text # 字符串类型 # 使用xml包中的elementtree解析xml格式内容 # xml接收一个字符串作为参数,将其格式化特殊的对象 node = et.xml(result) #获取内容 if node.text =='y': print('在线')
import requests response2 = requests.get('http://www.webxml.com.cn/webservices/traintimewebservice.asmx/getdetailinfobytraincode?traincode=k234&userid=starpinlan') result2 = response2.text #字符串str from xml.etree import elementtree as et root = et.xml(result2) #<class 'xml.etree.elementtree.element'> # print(type(node2)) for node in root.iter('traindetailinfo'): #iter方法是找到root这个对象中的后代标签名是traindetailinfo的所有元素 print(node.tag,node.attrib) #输出它的标签名,以及它的属性 print(node.find('trainstation').text) #find方法是找到指定名称的第一个子标签
1.2 遍历xml文档的指定节点
- 创建一个xml文档,写入如下内容:
s1 = ''' <data> <country name="liechtenstein"> <rank updated="yes">2</rank> <year id="year">2024</year> <gdppc>141100</gdppc> <neighbor direction="e" name="austria" /> <neighbor direction="w" name="switzerland" /> </country> <country name="singapore"> <rank updated="yes">5</rank> <year id="year">2027</year> <gdppc>59900</gdppc> <neighbor direction="n" name="malaysia" /> </country> <country name="panama"> <rank updated="yes">69</rank> <year id="year">2027</year> <gdppc>13600</gdppc> <neighbor direction="w" name="costa rica" /> <neighbor direction="e" name="colombia" /> </country> </data> ''' with open('xmltest.xml','w+',encoding='utf-8') as f: f.write(s1) f.flush()
- 读取xml文档,不修改原文件
from xml.etree import elementtree as et #使用xml格式化字符串 root = et.xml(open('xmltest.xml',encoding='utf-8').read()) #此种方式只能读取,不可修改文件 print(root.tag) for node in root.iter('country'): print(node.tag,node.attrib,node.find('year').text) child_node = node.find('year') #找到标签名为year的所有节点 new_year = int(child_node.text)+1 #将year标签的值加1 child_node.text = str(new_year) child_node.set('name','year') #设置属性name,其值为year # del child_node.attrib['name'] #删除name属性键值对 #保存文件需要另创建一个新文件 tree = et.elementtree(root) #创建一个内容为root的elementtree对象 tree.write('newxml.xml',encoding='utf-8') #一定要通过write写入文件。
- 使用parse方法解析文件,可以修改原文件。
#使用elementtree的parse方法解析文件 from xml.etree import elementtree as et tree = et.parse('xmltest.xml') #parse方法可以打开文件,并解析其内容 # print(tree,type(tree)) # <class 'xml.etree.elementtree.elementtree'> root = tree.getroot() # getroot方法获得最顶层的根节点 # print(root.tag) # data for node in root.iter('year'): print(node.tag,node.text) new_year = int(node.text) + 1 node.text = str(new_year) node.set('id','year') # 设置id属性,其值为year, print(node.attrib) # attrib是字典形式 tree.write('xmltest.xml') #parse可以直接修改原文件
- 查看一个节点都有哪些方法
from xml.etree import elementtree as et tree = et.parse('xmltest.xml') root = tree.getroot() print(dir(root)) #查看节点都有哪些方法 ''' ['__class__', '__copy__', '__deepcopy__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'attrib', 'clear', 'extend', 'find', 'findall', 'findtext', 'get', 'getchildren', 'getiterator', 'insert', 'items', 'iter', 'iterfind', 'itertext', 'keys', 'makeelement', 'remove', 'set', 'tag', 'tail', 'text'] #常用tag,attrib,find,text,set,iter,get,append,clear,extend,findall,getchildren,insert,makeelement '''
1.3 通过python手工创建xml文档
from xml.etree import elementtree as et root = et.element('namelist') #通过element类创建一个名为namelist的xml元素(对象) print(root,type(root)) # <element 'namelist' at 0x00000184ad6c21d8> <class 'xml.etree.elementtree.element'> name1 = et.subelement(root,'name',attrib={'enrolled':'yes'}) # 给root创建子节点,子节点的标签名是name,属性 name1.text = 'lanxing' #给内容赋值 age1 = et.subelement(name1,'age',attrib={'checked':'no'}) # 给name1创建子节点 age1.text = '18' sex1 = et.subelement(name1,'sex',attrib={'sex':'male'}) sex1.text = 'male' name2 = et.subelement(root,'name',attrib={'enrolled':'yes'}) # 给root创建子节点,子节点的标签名是name,属性 name2.text = '蓝星' #给内容赋值 age2 = et.subelement(name2,'age',attrib={'checked':'no'}) # 给name1创建子节点 age2.text = '28' # 必须是字符串才可以序列化 sex2 = et.subelement(name2,'sex',attrib={'sex':'male'}) sex2.text = 'female' tree = et.elementtree(root) # 通过elementtree类生成文档对象 tree.write('xmltest2.xml',encoding='utf-8',xml_declaration=true) #将文档对象写入文件,declaration表示声明文件,相当于注释。
1.4 创建节点的两种方式
from xml.etree import elementtree as et tree = et.parse('xmltest.xml') root = tree.getroot() # 创建新节点的第一种方式:makeelement son = root.makeelement('son',{'sex':'male'}) print(son,type(son)) # <element 'son' at 0x000002e1e1b10138> <class 'xml.etree.elementtree.element'> # 创建新节点的第二种方式:通过element类进行创建,实际第一种方式也是调用element类 son2 = et.element('son2',{'sex':'male'}) son2.text = '男' # 将新节点添加到root上 root.append(son) root.append(son2) tree.write('xmltest.xml',encoding='utf-8',short_empty_elements=false) # short参数是控制是否可简写的。
1.5 总结
xml: 1,解析: str:elementtree.xml(str) 文件:elementtree.parse(file) 2,element对象操作: tag,text,find,iter,get,set,findall,append,insert,remove。 3,重新写入文件: elementtree(element(tag,attrib)).write(filepath,encoding=none) 必须是elementtree对象才有写入方法。 4,创建xml: root= element(tag,attrib) ele = root.makeelement(tag,attrib) root.append(ele) elementtree.subelement(root,tag,attrib) 5,缩进 from xml.dom import minidom def prettify(root): '''将节点转换成字符串,并添加缩进''' rough_string = et.tostring(root,'utf-8') reparsed = minidom.parsestring(rough_string) return reparsed.topprettyxml(indent='\t') 6,命名空间 7,非常重要 一切皆对象,type(obj)查看对象的类。dir(obj)查看对象具有的方法。
2. configparser模块
configparser模块用来处理配置文件,配置文件是以.ini结尾的文件,长得像下面这样。
[autoupdate] #[xxx]叫做节点
configfileurl = # 键值对,左边的叫key,右边的叫value
autoupdatecheckdelay = 30
configfilekey1 = edad921681272c3e37f34020450a6963
configfilekey2 = 132150629469920000
lstm_autoupdate = 1570589347
isautoupdate = 0[packageinstallinfo]
default = 2
c6aa1078e4d92ff0573452220ca2d8ae = 4
import configparser con = configparser.configparser() # 创建一个configparser对象 con.read('config.ini',encoding='utf-8') # 打开文件并读取文件内容,放进内存 # 1,获取所有节点 # con对象的sections方法,内存中寻找所有的[xxx],一个[xxx]就是一个配置文件的节点 ret = con.sections() # 获取所有的节点名称,并返回一个列表 print(ret) # ['autoupdate', 'packageinstallinfo'] # 2,获取指定节点下所有的键值对,将key与值作为元组,元组作为列表的元素返回。 ret2 = con.items('autoupdate') print(ret2) # [('configfileurl', 'https://update.pan.baidu.com/autoupdate'), ('isautoupdate', '0'), ('autoupdatecheckdelay', '30'), ('configfilekey1', 'edad921681272c3e37f34020450a6963'), ('configfilekey2', '132150629469920000'), ('lstm_autoupdate', '1570589347')] # 3,获取指定节点所有的键 ret3 = con.options('packageinstallinfo') print(ret3) # ['default', 'c6aa1078e4d92ff0573452220ca2d8ae'] # 4, 获取指定节点下指定key的值,get(sections,key) value1 = con.get('packageinstallinfo','default') #默认返回字符串 print(value1,type(value1)) # 可以使用getint方法,自动将字符串转换为整数返回 value2 = con.getint('packageinstallinfo','default') print(value2,type(value2)) # 可以使用getfloat方法,自动将字符串转换为浮点数返回 value3 = con.getfloat('packageinstallinfo','default') print(value3,type(value3)) # 如果值是布尔值,可以使用getboolean方法,自动将字符串转换为布尔值返回 # value4 = con.getboolean('packageinstallinfo','default') # 会报错,因为其值不是布尔值 # 5,检查,添加,删除节点 has_sec = con.has_section('autoupdate') #判断是否有节点,如果有返回true print(has_sec) con.add_section('name') con.remove_section('name') # 添加,删除操作必须重新写入文件,否则不能持久化保存。 # 6,检查,删除,设置指定节点内的键值对 #检查 has_opt =con.has_option('autoupdate','isautoupdate') #删除 con.remove_option('autoupdate','isautoupdate') #设置 con.set('autoupdate','isautoupdate','0') con.write(open('config.ini','w')) #write写入得接收一个文件对象
4. shutil模块
shutil模块是高级的文件,文件夹,压缩包处理模块。
import shutil # 将文件内容复制到另一个文件中 # shutil.copyfileobj(fsrc,fdst[,length]) 将一个文件流对象复制给另一个文件流对象,长度是可选的。 f1 =open('1.txt','r',encoding='utf-8') f2 =open('2.txt','w',encoding='utf-8') shutil.copyfileobj(f1,f2) f1.close() f2.close() # shutil.copyfile(src,dst),复制文件 shutil.copyfile('1.txt','3.txt') # shutil.copymode(src,dst) 仅复制文件的权限,用户,组和内容都不变 shutil.copymode('1.txt','2.txt') #dst要存在 # shutil.copystat(src,dst) 仅拷贝状态的信息,包括:mode bits, atime, mtime, flags shutil.copystat('1.txt', '2.txt') # shutil.copy(src,dst) #复制文件和权限 shutil.copy('1.txt','2.txt') # shutil.copy2(src,dst) # 复制文件和状态信息 shutil.copy2('1.txt','2.txt') # shutil.ignore_patterns(*patterns)忽略某些格式的文件 # shutil.copytree(src, dst, symlinks=false, ignore=none) 递归地去复制文件夹 shutil.copytree('.','../day10',symlinks=true,ignore=shutil.ignore_patterns('*.py')) # shutil.rmtree(path[, ignore_errors[, onerror]]) shutil.rmtree('../day10')# 递归的去删除文件 # shutil.move(src, dst) 递归的去移动文件,它类似mv命令,其实就是重命名。 shutil.make_archive(base_name, format[,root_dir[,owner[,group[,logger]]]]) # 创建压缩包并返回文件路径, # 其中base_name是指压缩包的文件包,也可以压缩包的路径。 # format:压缩包种类,zip,tar,bztar,gztar. # root_dir: 要压缩的文件夹路径(默认当前目录) # owner:用户,默认当前用户 # group:组,默认当前组 # logger:用于记录日志,通常是logging.logger对象 shutil.make_archive('../test1','tar','.')
shutil 对压缩包的处理是调用 zipfile 和 tarfile 两个模块来进行的,
import zipfile # 压缩 z = zipfile.zipfile('laxi.zip', 'w') #创建一个zip的压缩包对象 z.write('a.log') # 往压缩包里面加入文件 z.write('data.data') z.close() # 解压 z = zipfile.zipfile('laxi.zip', 'r') z.extractall() # 解压所有文件 print(z.namelist()) # 获得压缩包内的所有文件名 z.extract('1.txt') # 单独解压指定文件 z.close() import tarfile # 压缩 tar = tarfile.open('your.tar','w') # 创建tar格式的压缩包 tar.add('/users/wupeiqi/pycharmprojects/bbs2.log', arcname='bbs2.log') #往里面加入压缩文件,可以另外设置名字为bbs2.log tar.add('/users/wupeiqi/pycharmprojects/cmdb.log', arcname='cmdb.log') tar.close() # 解压 tar = tarfile.open('your.tar','r') tar.extractall() # 可设置解压地址 print(tar.getmembers()) #返回压缩包内的所有文件名 tar.extractfile('1.txt') #单独解压指定文件 tar.close()
5. subprocess模块
专门用于python执行系统命令
import subprocess ret = subprocess.call('ipconfig') # call执行系统命令,返回状态码 print(ret) # 成功的返回码是0 ret2 = subprocess.check_call('ipconfig') # 执行命令,返回状态码 print(ret2) ret3 = subprocess.check_output('ipconfig') # 执行命令,返回字节类型的命令结果 print(ret3) ''' 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()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等 ''' subprocess.popen('mkdir test',shell=true,cwd='.') # shell是true的情况下,就是将前面的字符串当作命令来输入 subprocess.popen(['ipconfig','dir']) # 执行多个命令 obj = subprocess.popen(["python"], stdin=subprocess.pipe, stdout=subprocess.pipe, stderr=subprocess.pipe, universal_newlines=true) obj.stdin.write("print(1)\n") obj.stdin.write("print(2)") obj.stdin.close() cmd_out = obj.stdout.read() obj.stdout.close() cmd_error = obj.stderr.read() obj.stderr.close() print(cmd_out) print(cmd_error)