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()

 

posted @ 2019-09-16 11:40  Wolf_Coder  阅读(698)  评论(0编辑  收藏  举报