python基础之psutil模块和发邮件(smtplib和yagmail)
除了内建的模块外,Python还有大量的第三方模块。
基本上,所有的第三方模块都会在PyPI - the Python Package Index上注册,只要找到对应的模块名字,即可用pip安装。
此外,安装Anaconda模块后,数十个常用的第三方模块就已经就绪,不用pip手动安装。
一、psutil
psutil = process and system utilities,它不仅可以通过一两行代码实现系统监控,还可以跨平台使用,支持Linux/UNIX/OSX/Windows等,是系统管理员和运维小伙伴不可或缺的必备模块。
psutil是一个跨平台库能够轻松实现获取系统运行的进程和系统利用率(包括CPU、内存、磁盘、网络等)信息。它主要应用于系统监控,分析和限制系统资源及进程的管理。它实现了同等命令行工具提供的功能,如ps、top、lsof、netstat、ifconfig、who、df、kill、free、nice、等。
1、安装
(venv) C:\Users\renyz02\Desktop\py_test1>pip install psutil Collecting psutil Downloading https://files.pythonhosted.org/packages/7c/58/f5d68ddca37480d8557b8566a20bf6108d7e1c6c9b9208ee0786e0cd012b/psutil-5.6. 3-cp37-cp37m-win_amd64.whl (234kB) 100% |████████████████████████████████| 235kB 85kB/s Installing collected packages: psutil Successfully installed psutil-5.6.3
2、常用命令
#内存使用情况 # mem = psutil.virtual_memory() # print(mem) #cpu使用率 # cpu = psutil.cpu_percent(1) # print(cpu) #硬盘使用情况 # disk = psutil.disk_usage('d:') # print(disk[1]) #1、查看cpu所有信息 print(psutil.cpu_times()) #2、显示cpu所有逻辑信息 print(psutil.cpu_times(percpu=True)) #3、查看用户的cpu时间比 print(psutil.cpu_times().user) #4、查看cpu逻辑个数 print(psutil.cpu_count()) #查5、看系统内存 mem = psutil.virtual_memory() print(mem) #5.1 系统已经使用内存 print(mem.used) #5.2 系统空闲内存 print(mem.free) # 5.3系统总计内存 print(mem.total) #5.4 获取swap内存信息 print(psutil.swap_memory())
3、例子:
(1)获取CPU信息
import psutil #导入psutil模块 print(psutil.cpu_times()) #统计CPU的用户/系统/空闲时间 print(psutil.cpu_count()) #CPU逻辑数量 print(psutil.cpu_count(logical=False)) #CPU物理核心 #实现类似top命令的CPU使用率,每秒刷新一次,累计10次: for i in range(10): print(psutil.cpu_percent(interval=1,percpu=True)) ----------------------------------------------------------------------------------- scputimes(user=737.03125, system=514.390625, idle=17152.640625, interrupt=12.0625, dpc=55.984375) 2 2 [10.8, 13.6] [7.8, 9.2] [18.8, 19.7] [7.7, 13.4] [4.6, 7.5] [26.6, 18.5] [1.6, 0.0] [0.0, 3.1] [1.5, 1.5] [10.8, 9.1]
(2)获取内存信息
import psutil print(psutil.virtual_memory()) #物理内存 print(psutil.swap_memory()) #交换内存 --------------------------------------------------- svmem(total=2146287616, available=560144384, percent=73.9, used=1586143232, free=560144384) sswap(total=3287138304, used=1749319680, free=1537818624, percent=53.2, sin=0, sout=0)
返回的是字节为单位的整数
(3)获取磁盘信息
import psutil print(psutil.disk_partitions()) #磁盘分区信息 print(psutil.disk_usage("/")) #磁盘使用情况 print(psutil.disk_io_counters()) #磁盘IO ---------------------------------------------------------------- [sdiskpart(device='C:\\', mountpoint='C:\\', fstype='NTFS', opts='rw,fixed'), sdiskpart(device='D:\\', mountpoint='D:\\', fstype='UDF', opts='ro,cdrom')] sdiskusage(total=42356174848, used=17351532544, free=25004642304, percent=41.0) sdiskio(read_count=145858, write_count=32079, read_bytes=3212907008, write_bytes=1443702784, read_time=2166, write_time=1402)
(4)获取网络信息
import psutil print(psutil.net_io_counters()) #获取网络读写字节/包的个数 ---------------------------------- snetio(bytes_sent=985568, bytes_recv=21143273, packets_sent=10516, packets_recv=18128, errin=0, errout=0, dropin=0, dropout=0) ------------------------------------------------------------------------------- print(psutil.net_connections()) #获取当前网络的连接信息 ------------------------------------------------------------------------------- print(psutil.net_if_addrs()) #获取网络接口信息 ---------------------------------- {'Ethernet0': [snicaddr(family=<AddressFamily.AF_LINK: -1>, address='00-0C-29-E6-FD-15', netmask=None, broadcast=None, ptp=None), snicaddr(family=<AddressFamily.AF_INET: 2>, address='192.168.11.132', netmask='255.255.255.0', broadcast=None, ptp=None), snicaddr(family=<AddressFamily.AF_INET6: 23>, address='fe80::7555:6b7:e149:498d', netmask=None, broadcast=None, ptp=None)], 'isatap.localdomain': [snicaddr(family=<AddressFamily.AF_LINK: -1>, address='00-00-00-00-00-00-00-E0', netmask=None, broadcast=None, ptp=None), snicaddr(family=<AddressFamily.AF_INET6: 23>, address='fe80::5efe:192.168.11.132', netmask=None, broadcast=None, ptp=None)], '本地连接* 3': [snicaddr(family=<AddressFamily.AF_LINK: -1>, address='00-00-00-00-00-00-00-E0', netmask=None, broadcast=None, ptp=None), snicaddr(family=<AddressFamily.AF_INET6: 23>, address='2001:0:34f1:8072:2c79:b29:3f57:f47b', netmask=None, broadcast=None, ptp=None), snicaddr(family=<AddressFamily.AF_INET6: 23>, address='fe80::2c79:b29:3f57:f47b', netmask=None, broadcast=None, ptp=None)], 'Loopback Pseudo-Interface 1': [snicaddr(family=<AddressFamily.AF_INET: 2>, address='127.0.0.1', netmask='255.0.0.0', broadcast=None, ptp=None), snicaddr(family=<AddressFamily.AF_INET6: 23>, address='::1', netmask=None, broadcast=None, ptp=None)]} ------------------------------------------------------------------------------- print(psutil.net_if_stats()) #获取网络接口状态 --------------------------------- {'Ethernet0': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=1000, mtu=1500), 'Loopback Pseudo-Interface 1': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=1073, mtu=1500), 'isatap.localdomain': snicstats(isup=False, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=0, mtu=1280), '本地连接* 3': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=0, mtu=1472)}
(5)获取进程信息
>>> psutil.pids() # 所有进程ID [3865, 3864, 3863, 3856, 3855, 3853, 3776, ..., 45, 44, 1, 0] >>> p = psutil.Process(3776) # 获取指定进程ID=3776,其实就是当前Python交互环境 >>> p.name() # 进程名称 'python3.6' >>> p.exe() # 进程exe路径 '/Users/michael/anaconda3/bin/python3.6' >>> p.cwd() # 进程工作目录 '/Users/michael' >>> p.cmdline() # 进程启动的命令行 ['python3'] >>> p.ppid() # 父进程ID 3765 >>> p.parent() # 父进程 <psutil.Process(pid=3765, name='bash') at 4503144040> >>> p.children() # 子进程列表 [] >>> p.status() # 进程状态 'running' >>> p.username() # 进程用户名 'michael' >>> p.create_time() # 进程创建时间 1511052731.120333 >>> p.terminal() # 进程终端 '/dev/ttys002' >>> p.cpu_times() # 进程使用的CPU时间 pcputimes(user=0.081150144, system=0.053269812, children_user=0.0, children_system=0.0) >>> p.memory_info() # 进程使用的内存 pmem(rss=8310784, vms=2481725440, pfaults=3207, pageins=18) >>> p.open_files() # 进程打开的文件 [] >>> p.connections() # 进程相关网络连接 [] >>> p.num_threads() # 进程的线程数量 1 >>> p.threads() # 所有线程信息 [pthread(id=1, user_time=0.090318, system_time=0.062736)] >>> p.environ() # 进程环境变量 {'SHELL': '/bin/bash', 'PATH': '/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:...', 'PWD': '/Users/michael', 'LANG': 'zh_CN.UTF-8', ...} >>> p.terminate() # 结束进程 Terminated: 15 <-- 自己把自己结束了
psutil还提供了一个test()
函数,可以模拟出ps
命令的效果:
import psutil print(psutil.test()) -------------------------------------------------------------------- USER PID %MEM VSZ RSS NICE STATUS START TIME CMDLINE SYSTEM 0 0.0 0.0B 4.0K runni 07:55 22:20 System Idle P SYSTEM 4 3.6 556.0K 74.3M 32 runni 07:55 00:54 System SYSTEM 252 0.2 1.2M 4.8M 32 runni 07:56 00:00 C:\Program Fi SYSTEM 264 0.0 348.0K 908.0K 32 runni 07:56 00:00 \SystemRoot\S SYSTEM 284 2.0 32.6M 40.4M 32 runni 07:56 00:41 C:\Windows\sy SYSTEM 388 0.2 1.2M 3.1M 32 runni 07:56 00:00 %SystemRoot%\ LOCAL SER 448 1.0 7.8M 20.5M 32 runni 07:56 00:12 C:\Windows\sy SYSTEM 456 0.2 944.0K 4.1M 128 runni 07:56 00:00 wininit.exe SYSTEM 472 0.3 1.4M 6.9M 32 runni 07:56 00:19 %SystemRoot%\
二、smtplib(发送邮件)
使用python发送QQ邮件时,用到了Python的两个包来发送邮件: smtplib 和 email 。
(1)Python 的 email 模块里包含了许多实用的邮件格式设置函数,可以用来创建邮件“包裹”。使用的 MIMEText 对象,为底层的 MIME(Multipurpose Internet MailExtensions,多用途互联网邮件扩展类型)协议传输创建了一封空邮件,最后通过高层的SMTP 协议发送出去。
MIMEText 对象 msg 包括收发邮箱地址、邮件正文和主题,Python 通过它就可以创建一封格式正确的邮件。
(2)smtplib :模块用来设置服务器连接的相关信息。
要想通过QQ邮箱来发送邮件,需要开启QQ邮箱的设置-账户里SMTP服务,接下来会通过发送短信验证来获得授权码,有了授权码后就可以在代码里添加了。
Python对SMTP支持有smtplib和email两个模块:
Email:模块里包含了许多实用的邮件格式设置函数,负责构造邮件,
Smtplib:模块用来设置服务器连接的相关信息,负责发送邮件。
1、开启qq邮箱SMTP服务器
(1)POP3是Post Office Protocol 3的简称,即邮局协议的第3个版本,是TCP/IP协议族中的一员(默认端口是110)。本协议主要用于支持使用客户端远程管理在服务器上的电子邮件。
(2)SMTP/IMAP
2、Python SMTPf发送邮件
SMTP(Simple Mail Transfer Protocol)邮件传输通讯协议
SMTP是互联网上的一种通讯协议,主要功能是用在传送电子邮件,当我们通过电子邮件程序,寄E-mil给另外一个人时,必须通过SMTP通讯协议,将邮件送到对方的邮件服务器上,等到对方上网的时候,就可以收到你所寄的信。
#!/usr/bin/env python # -*- coding:utf-8 -*- # Author: Renyz #python发送邮件实战 import smtplib from email.mime.text import MIMEText msg = MIMEText("人生苦短,难得糊涂","plain",'utf-8') # 构建文本内容 # 类似于写信的标题 msg["Subject"] = "你好,python" # 定义邮件标题 msg["From"] = "2367880638@qq.com" # 定义邮件发件人 # 登录到SMTP服务器 server = smtplib.SMTP_SSL("smtp.qq.com",465) # 实例化服务器 #使用自己的邮箱和账号进行登录 server.login("2367880638@qq.com","chsidomjkblndhgd") # 授权码;# SMTP:chsidomjkblndhgd server.sendmail("2367880638@qq.com",["1249773850@qq.com", "12312312321312@qq.com", ],msg.as_string()) # 发送邮件 server.quit() # 退出服务器 # POP3:auktyhhaoufdecdc # SMTP:chsidomjkblndhgd
参数说明:
host: SMTP 服务器主机。 你可以指定主机的ip地址或者域名如: runoob.com,这个是可选参数。
port: 如果你提供了 host 参数, 你需要指定 SMTP 服务使用的端口号,一般情况下 SMTP 端口号为25。
参数说明:local_hostname: 如果 SMTP 在你的本机上,你只需要指定服务器地址为 localhost 即可。
Python SMTP 对象使用 sendmail 方法发送邮件,语法如下:
import smtplib smtpobj = smtplib.SMTP(host='', port=0, local_hostname=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, source_address=None)
from_addr: 邮件发送者地址。
to_addrs: 字符串列表,邮件发送地址。
msg: 发送消息
这里要注意一下第三个参数,msg 是字符串,表示邮件。我们知道邮件一般由标题,发信人,收件人,邮件内容,附件等构成,发送邮件的时候,要注意 msg 的格式。这个格式就是 smtp 协议中定义的格式。
三、yagmail模块
1、下载
(venv) C:\Users\renyz02\Desktop\py_test1>pip install yagmail Collecting yagmail Downloading https://files.pythonhosted.org/packages/f6/5b/1e7ec5a612c831154cb1dd01f4211f4e4501083084e3d9e5ed9789698624/yagmail-0.1 1.220-py2.py3-none-any.whl Installing collected packages: yagmail Successfully installed yagmail-0.11.220
2、发送邮件
import yagmail #连接邮箱服务器 yag = yagmail.SMTP(user='2367880638@qq.com', password='chsidomjkblndhgd', host='smtp.qq.com') # 发送邮件 yag.send(to=['2367880638@qq.com','1249773850@qq.com'], subject='这是测试邮件标题', contents=['这是测试邮件的内容',r'C:\Users\renyz02\Desktop\皮卡丘.py']) # 断开连接 yag.close()
注意:
如果遇到ModuleNotFoundError错误时,有两种可能,一种是未导入包,导入或者下载即可;另一种是包名和文件名冲突,只需要将文件名修改一下即可。
四、监控主机的系统信息
#!/usr/bin/env python # -*- coding:utf-8 -*- # Author: Renyz import psutil import yagmail # import time def cpu(): cpu = psutil.cpu_percent(1) return {'cpu_percent':cpu} def disk(): disk_c = psutil.disk_usage('c:')[3] disk_d = psutil.disk_usage('d:')[3] return {'disk_c':disk_c,'disk_d':disk_d} def mem(): mem = psutil.virtual_memory() total_mem = int(mem[0]/1024/1024) percent_mem = mem[2] return {'total_mem':total_mem,'percent_mem':percent_mem} def sendmail(sub,content): yag = yagmail.SMTP(user='2367880638@qq.com', password='chsidomjkblndhgd', host='smtp.qq.com') yag.send('2367880638@qq.com',sub,content) yag.close() def main(): total_info = cpu() disk_info = disk() mem_info = mem() total_info.update(disk_info) total_info.update(mem_info) content = '%s' % total_info if total_info.get('cpu_percent') > 1: sendmail('cpu报警',content) print('cpu邮件') elif total_info.get('disk_c') > 80: sendmail('C盘报警',content) print('c盘邮件') elif total_info.get('disk_d') > 80: sendmail('D盘报警',total_info) print('D盘邮件') elif total_info.get('percent_mem') > 80: sendmail('内存报警',total_info) print('内存邮件') if __name__ == '__main__': main()