回顾
- os.path.dirname(fileName):获取文件的上级路径
- 全部变量__file__:获取文件的全路径
- os.path.join(path,fileName):拼接路径
- __builtins__:所有的内置函数都在里面(以后会用)
- urllib & requests 作用:发送http请求,并获取返回值
XML
- xml解析(2中解析方式)
from xml.etree import ElementTree as ET
# 第一种方式:得到一个Element对象
root = ET.XML(xmlStr)
# 第二种方式:得到一个ElementTree对象
tree = ET.parse('fileName')
root = tree.getroot()
-
Element类
- xml每一个节点都是Element类的对象
- Element api
- tag:获得当前节点的标签名
- attrib:当前标签的属性,返回字典对象
- text:当前标签的内容
- makeelement('eleName',{'att1':'val1',...})
- append(element):在节点里追加子节点
- remove(ele):删除节点,传入element对象
- find(eleName):根据节点名查找子节点
- findtext():
-
ElementTree类
- ElementTree创建方式:
-
ET.parse('fileName')
- 通过查看源代码,发现:
self.__class__(): # __class__代表当前类名
ET.ElementTree(rootEle)
-
- ElementTree api:
- getroot():获取根节点
- write(fileName):将xml回写到文件
- 在回写的过程中,如果标签内没有内容,默认回写得到的是自闭合的标签,如果不想得到自闭合的效果:(但是一般不这么用,浪费空间)
# 不自闭合 tree.write('fileName', short_empty_elemet = False)
- xml中如果有中文,回写时需要指定编码:
tree.write('fileName', encoding = 'utf-8')
- xml简介:在xml文件顶部添加xml的简介
tree.write('fileName', xml_declaration=True)
- ElementTree创建方式:
-
创建Element的三种方式
- ET.Element('tagName', {'attrib1':'val1',...})
- 创建的仅仅为Element对象,需要添加到节点中
- ele.makeelement('tagName', {'attrib1':'val1',...})
- 同上
- ET.subelement(ele,'tagName', {'attrib1':'val1',...})
- 在某个节点里创建子节点
- ET.Element('tagName', {'attrib1':'val1',...})
-
xml缩进:
- 通过ElementTree写到文件的xml不带缩进效果,如果想要有缩进的效果,需要用到另一个模块:
from xml.dom import minidom
- minidom模块也有对xml进行操作的功能,但是功能少,效率低,所以只用它的格式化功能
from xml.etree import ElementTree as ET from xml.dom import minidom root = ET.Element('root', {'attrib1': 'val1'}) son1 = root.makeelement('son1', {'attrib1': 'val1'}) son1.text = "son1_text" root.append(son1) ET.SubElement(root, 'son2', {'attrib1': 'val1', 'attrib2': 'val2'}) xml_str = ET.tostring(root, encoding='utf-8', short_empty_elements=True) parser = minidom.parseString(xml_str) pretty_xml = parser.toprettyxml() with open('pretty.xml', mode='w') as file: file.write(pretty_xml)
-
命名空间
- http://www.w3school.com.cn/xml/xml_namespaces.asp
from xml.etree import ElementTree as ET ET.register_namespace('com',"http://www.company.com") #some name # build a tree structure root = ET.Element("{http://www.company.com}STUFF") body = ET.SubElement(root, "{http://www.company.com}MORE_STUFF", attrib={"{http://www.company.com}hhh": "123"}) body.text = "STUFF EVERYWHERE!" # wrap it in an ElementTree instance, and save as XML tree = ET.ElementTree(root) tree.write("page.xml", xml_declaration=True, encoding='utf-8', method="xml")
configparser
- configparser用于处理特定格式的文件,其本质是通过open来操作文件
# 注释
; 注释
[section1]
key1:value1
key2=value2
[setction2]
key1=value1
key2:value2
import configparser
parser = configparser.ConfigParser()
parser.read('conf', encoding='utf-8')
sections = parser.sections()
# 获取所有的section
print(sections) # ['section1', 'section2']
# 获取section下的键值对
items = parser.items('section1')
print(items) # [('key1', 'value1'), ('key2', 'value2')]
# 获取指定节点下所有的建
options = parser.options('section1')
print(options) #['key1', 'key2']
# 获取指定节点下指定key的值
value = parser.get('section1', 'key1')
print(value) # value1
# getint()/getfloat()/getboolean()
# 检查、删除、添加节点
hasSection = parser.has_section('section1')
print(hasSection) # True
parser.add_section('section3')
parser.remove_section('section1')
with open('conf', mode='w') as file:
parser.write(file)
# 检查、删除、设置指定组内的键值对
has_option = parser.has_option(section='section2',option='key1')
print(has_option) # True
parser.remove_option('section2', 'key2')
option3 = parser.set('section2','key3','val3')
with open('conf',mode='w') as file:
parser.write(file)
xml
- 删除属性:
- del node.attrib['attbitName']
requests
- 无参实例:
import requests
ret = requests.get('https://github.com/timeline.json')
print(ret.url)
print(ret.text)
- 有参实例:
import requests
payload = {'key1': 'value1', 'key2': 'value2'}
ret = requests.get("http://httpbin.org/get", params=payload)
print(ret.url)
print(ret.text)
- 基本post实例
import requests
payload = {'key1': 'value1', 'key2': 'value2'}
ret = requests.post("http://httpbin.org/post", data=payload)
print(ret.text)
- 发送请求头和数据实例
import requests
import json
url = 'https://api.github.com/some/endpoint'
payload = {'some': 'data'}
headers = {'content-type': 'application/json'}
ret = requests.post(url, data=json.dumps(payload), headers=headers)
print(ret.text)
print(ret.cookies)
- 其他请求
requests.get(url, params=None, **kwargs)
requests.post(url, data=None, json=None, **kwargs)
requests.put(url, data=None, **kwargs)
requests.head(url, **kwargs)
requests.delete(url, **kwargs)
requests.patch(url, data=None, **kwargs)
requests.options(url, **kwargs)
# 以上方法均是在此方法的基础上构建
requests.request(method, url, **kwargs)
- Http请求和XML实例
import urllib
import requests
from xml.etree import ElementTree as ET
# 使用内置模块urllib发送HTTP请求,或者XML格式内容
"""
f = urllib.request.urlopen('http://www.webxml.com.cn//webservices/qqOnlineWebService.asmx/qqCheckOnline?qqCode=424662508')
result = f.read().decode('utf-8')
"""
# 使用第三方模块requests发送HTTP请求,或者XML格式内容
r = requests.get('http://www.webxml.com.cn//webservices/qqOnlineWebService.asmx/qqCheckOnline?qqCode=424662508')
result = r.text
# 解析XML格式内容
node = ET.XML(result)
# 获取内容
if node.text == "Y":
print("在线")
else:
print("离线")
- 查看火车停靠信息
import urllib
import requests
from xml.etree import ElementTree as ET
# 使用内置模块urllib发送HTTP请求,或者XML格式内容
"""
f = urllib.request.urlopen('http://www.webxml.com.cn/WebServices/TrainTimeWebService.asmx/getDetailInfoByTrainCode?TrainCode=G666&UserID=')
result = f.read().decode('utf-8')
"""
# 使用第三方模块requests发送HTTP请求,或者XML格式内容
r = requests.get('http://www.webxml.com.cn/WebServices/TrainTimeWebService.asmx/getDetailInfoByTrainCode?TrainCode=G666&UserID=')
result = r.text
# 解析XML格式内容
root = ET.XML(result)
for node in root.iter('TrainDetailInfo'):
print(node.find('TrainStation').text,node.find('StartTime').text,node.tag,node.attrib)
logging模块
- 程序运行时经常遇到报错,日志记录等,如果让每个用户的操作都单独打开日志文件记录,会出现线程安全问题
- logging用于便捷记录日志且线程安全的模块
import logging
logging.basicConfig(filename='log.log',
format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p',level=10)
logging.debug('debug')
logging.info('info')
logging.warning('warning')
logging.error('error')
logging.critical('critical')
logging.log(10,'log')
- 日志等级
CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0
- 多文件日志
- logging拆分:
- 比较函数:信息等级:FileHandler
- 写入函数:对满条件的信息写入文件:Logger
- Logger + fileHandler
- logging拆分:
# 定义文件
file_1_1 = logging.FileHandler('l1_1.log', 'a', encoding='utf-8')
fmt = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s")
file_1_1.setFormatter(fmt)
file_1_2 = logging.FileHandler('l1_2.log', 'a', encoding='utf-8')
fmt = logging.Formatter()
file_1_2.setFormatter(fmt)
# 定义日志
logger1 = logging.Logger('s1', level=logging.ERROR)
logger1.addHandler(file_1_1)
logger1.addHandler(file_1_2)
# 写日志
logger1.critical('1111')
# 定义文件
file_2_1 = logging.FileHandler('l2_1.log', 'a')
fmt = logging.Formatter()
file_2_1.setFormatter(fmt)
# 定义日志
logger2 = logging.Logger('s2', level=logging.INFO)
logger2.addHandler(file_2_1)
- 如上述创建的两个日志对象
- 当使用【logger1】写日志时,会将相应的内容写入 l1_1.log 和 l1_2.log 文件中
- 当使用【logger2】写日志时,会将相应的内容写入 l2_1.log 文件中
系统命令-subprocess模块
- 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(...)
import subprocess
ret1 = subprocess.Popen(["mkdir","t1"])
ret2 = subprocess.Popen("mkdir t2", shell=True)
import subprocess
obj = subprocess.Popen("mkdir t3", shell=True, cwd='/home/dev',)
import subprocess
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)
import subprocess
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)")
out_error_list = obj.communicate()
print(out_error_list)
import subprocess
obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
out_error_list = obj.communicate('print("hello")')
print(out_error_list)
datatime
datetime.date:表示日期的类。常用的属性有year, month, day
datetime.time:表示时间的类。常用的属性有hour, minute, second, microsecond
datetime.datetime:表示日期时间
datetime.timedelta:表示时间间隔,即两个时间点之间的长度
timedelta([days[, seconds[, microseconds[, milliseconds[, minutes[, hours[, weeks]]]]]]])
strftime("%Y-%m-%d")
shutil
- 高级的 文件、文件夹、压缩包 处理模块
- 将文件内容拷贝到另一个文件中
import shutil
shutil.copyfileobj(open('old.xml','r'), open('new.xml', 'w'))
- shutil.copyfile(src, dst)
shutil.copyfile('f1.log', 'f2.log')
- 仅拷贝权限。内容、组、用户均不变
shutil.copymode('f1.log', 'f2.log')
- 仅拷贝状态的信息,包括:mode bits, atime, mtime, flags
shutil.copystat('f1.log', 'f2.log')
- shutil.copy(src, dst)
import shutil
shutil.copy('f1.log', 'f2.log')
- shutil.copy2(src, dst)
import shutil
shutil.copy2('f1.log', 'f2.log')
- 递归的去拷贝文件夹
mport shutil
shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))
import shutil
shutil.copytree('f1', 'f2', symlinks=True, ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))
- 递归的去删除文件
import shutil
shutil.rmtree('folder1')
- 递归的去移动文件,它类似mv命令,其实就是重命名
import shutil
shutil.move('folder1', 'folder3')
- 创建压缩包并返回文件路径,例如:zip、tar
#将 /Users/wupeiqi/Downloads/test 下的文件打包放置当前程序目录
import shutil
ret = shutil.make_archive("wwwwwwwwww", 'gztar', root_dir='/Users/wupeiqi/Downloads/test')
#将 /Users/wupeiqi/Downloads/test 下的文件打包放置 /Users/wupeiqi/目录
import shutil
ret = shutil.make_archive("/Users/wupeiqi/wwwwwwwwww", 'gztar', root_dir='/Users/wupeiqi/Downloads/test')
- shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的,详细:
import zipfile
# 压缩
z = zipfile.ZipFile('laxi.zip', 'w')
z.write('a.log')
z.write('data.data')
z.close()
# 解压
z = zipfile.ZipFile('laxi.zip', 'r')
z.extractall()
z.close()
import tarfile
# 压缩
tar = tarfile.open('your.tar','w')
tar.add('/Users/wupeiqi/PycharmProjects/bbs2.log', arcname='bbs2.log')
tar.add('/Users/wupeiqi/PycharmProjects/cmdb.log', arcname='cmdb.log')
tar.close()
# 解压
tar = tarfile.open('your.tar','r')
tar.extractall() # 可设置解压地址
tar.close()