常用模块介绍

孤街醉人 提交于 2020-03-25 03:10:27

subprocess模块

它是可以远程操作主机,模拟shell命令

'dir'是windows上查看任务的命令  

import subprocess
obj = subprocess.Popen('dir', shell=True,
                       stdout=subprocess.PIPE,
                       stderr=subprocess.PIPE)
#Popen是模拟cmd命令,'dir'是windows上查看任务的命令,shell=True是指可以用shell命令了, 输出和错误,放到管道(PIPE)里
# print(obj.stdout.read().decode('gbk')) #打印输出的内容
# print(obj.stderr.read().decode('gbk')) #打印错误的内容
res = obj.stdout.read() + obj.stderr.read() #错误和输入放到一起给变量res
print(res.decode('gbk')) #打印res

在linux里可以创建python脚本,写入

import subprocess
obj = subprocess.Popen('ls;lsblk', shell=True,
                       stdout=subprocess.PIPE,
                       stderr=subprocess.PIPE)
#Popen是模拟cmd命令,'dir'是windows上查看任务的命令,shell=True是指可以用shell命令了, 输出和错误,放到管道(PIPE)里
# print(obj.stdout.read().decode('utf-8')) #打印输出的内容
# print(obj.stderr.read().decode('utf-8')) #打印错误的内容
res = obj.stdout.read() + obj.stderr.read() #错误和输入放到一起给变量res
print(res.decode('utf-8')) #打印res

 socket模块

服务端步骤:

1、socket创建一个套接字

2、bind绑定ip和port

3、listen使套接字变为可以被动连接

4、accept等待客户端的连接

5、recv/send接收发送数据

import socket #导入模块
server = socket.socket()#创建实例,传给server,默认TCPIP ipv4
server.bind(('0.0.0.0', 8888))#0000代表暴露所有IP,或者冒号里边空着,也可以输入指定IP
server.listen(5)#监听最大5个链接
print('等待电话。。。')
conn, addr = server.accept()#链接和addr需要分别赋值,等待客户端连接,没有链接就等待
print('电话来了。。。')
#服务器接收消息
data = conn.recv(1024) #接收消息,大小为1024
print(data.decode('utf-8'))
#服务器发送消息
nfo = input('===>:')
conn.send(info.encode('utf-8'))

客户端步骤:

1、创建套接字

2、连接服务器

3、发送数据,最大接收1024字节

4、关闭套接字

import socket
client = socket.socket()
client.connect(('localhost', 8888))#如果是远程链接要写IP
#客户发送消息
info = input('===>:')
client.send(info.encode('utf-8'))
#客户接收消息
data = client.recv(1024)
print(data.decode('utf-8'))

先运行客户端,进入等待链接,然后运行服务端链接,输入聊天内容,回车发送,切换到客户端,回复收到的消息,这样就完成了聊天的过程,但是一人说一句后,我们看到程序结束了,那我们没聊够怎么办,对,加个循环。

我们在“服务器接收消息”和“客户端发送消息”之前加入while True:

并且下方整体缩进。

import socket #导入模块
server = socket.socket()#创建实例,传给server,默认TCPIP ipv4
server.bind(('0.0.0.0', 8888))#0000代表暴露所有IP,或者冒号里边空着,也可以输入指定IP
server.listen(5)#监听最大5个链接
print('等待电话。。。')
conn, addr = server.accept()#链接和addr需要分别赋值,等待客户端连接,没有链接就等待
print('电话来了。。。')
#服务器接收消息
while True:
    data = conn.recv(1024) #接收消息,大小为1024
    print(data.decode('utf-8'))
    #服务器发送消息
    info = input('===>:')
    conn.send(info.encode('utf-8'))
import socket
client = socket.socket()
client.connect(('localhost', 8888))#如果是远程链接要写IP
#客户发送消息
while True:
    info = input('===>:')
    client.send(info.encode('utf-8'))
    #客户接收消息
    data = client.recv(1024)
    print(data.decode('utf-8'))

这样我们就可以尽情的发送消息了

 

不过,当我们什么也不输入那么,会发现程序卡住了,再输入的内容(酷酷酷酷酷),也无法发送了,针对此,我们再原代码的基础上,客户端和服务端的发送条件加入为空循环

那么运行后,输入为空回车,将会重新上输入

 

这个时候我们发现,客户端没有发消息的话,那么服务端将一直等待,无法发送,整个程序处在半双工的情况下,所以我们要改成全双工,可以自由发送,那么就需要创建函数进程了

服务端:

import socket 
import threading
server = socket.socket()
server.bind(('0.0.0.0', 8888))
server.listen(5)
print('等待电话。。。')
conn, addr = server.accept()
print('电话来了。。。')
def recv():
    while True:
        # 服务器接收消息
        data = conn.recv(1024) 
        print(data.decode('utf-8'))
def send():
    while True:
        # 服务器发送消息
        info = input('===>:')
        if not info:continue
        conn.send(info.encode('utf-8'))
t1 = threading.Thread(target=recv)
t2 = threading.Thread(target=send)
t1.start()
t2.start()

客户端:

import socket
import threading
client = socket.socket()
client.connect(('localhost', 8888))
def send():
    while True:
        # 客户发送消息
        info = input('===>:')
        if not info:continue
        client.send(info.encode('utf-8'))
def recv():
    while True:
        #客户接收消息
        data = client.recv(1024)
        print(data.decode('utf-8'))

t1 = threading.Thread(target=send)
t2 = threading.Thread(target=recv)
t1.start()
t2.start()

到此,一个聊天程序就基本成型了

进阶修炼:链接Linux,模拟远程控制

import socket
import subprocess
import threading
server = socket.socket()
server.bind(('', 8888))
server.listen(5)
print('等待电话.....')
conn, addr = server.accept()
print('电话来了......')
while True:
    data = conn.recv(10240)
    cmd = subprocess.Popen(data.decode('utf-8'),
                           shell=True,
                           stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE)
    stdout = cmd.stdout.read()
    stderr = cmd.stderr.read()
    conn.send(stdout + stderr)

链接成功后,客户端输入的命令,可以得到相应的反馈结果 

如:输入ls -l

 例:通过读写复制文件

with open(r'‪C:\Users\逸轩\Desktop\w.txt', 'rb')as f:#二进制读
    data = f.read()
with open(r'a.txt', 'wb')as f:#二进制写
    f.write(data)

查看端口通不通

import socket
client = socket.socket()
result = client.connect_ex(('192.168.11.128', 22))
print(result)

运行结果:返回值为,说明通了,否则没通

re模块

.*?非贪婪匹配,根据要求尽可能的少找

.*贪婪匹配,尽可能的多找

按要求截取213123 和 12

import re
info = 'qwffq213123feqfeqwf2132fd1f12rf1f21f'

result1 = re.compile('fq(.*?)fe.*?1f(.*?)rf').findall(info)#加括号的代表要取的,不加括号的代表忽略的
t = result1[0]
res = ''.join(t)#把元组拼接成字符串
print(res)

运行结果:

取所有数字

import re
info = 'qwffq213123feqfeqwf2132fd1f12rf1f21f'

res = re.compile('(\d+)').findall(info)#findall匹配所有
result = ''.join(res)#把列表拼接成字符串
print(result)

运行结果:

取“qwffq”和“fe”之间的内容

import re
info = 'qwffq213123feqfeqwf2132fd1f12rf1f21f'

res = re.compile('qwffq(.*?)fe').findall(info)
print(res)

运行结果:

监控测试主机与端口通不通

import re
import socket
def sendmail(aa):
    import smtplib
    from email.mime.text import MIMEText
    from email.header import Header
    sender = 'liketimes@163.com'#发送的邮箱
    receiver = 'liketimes@163.com'#接收的邮箱
    subject = '报警'#邮件标题
    username = 'liketimes@163.com'#邮箱用户名
    password = '123qwe'#邮箱密码
    msg = MIMEText(aa, 'plain', 'utf-8')
    msg['Subject'] = Header(subject, 'utf-8')
    msg['From'] = 'Tim<liketimes@163.com>'#发送邮箱
    msg['To'] = 'liketimes@163.com'#接收邮箱
    smtp = smtplib.SMTP()
    smtp.connect('smtp.163.com')
    smtp.login(username, password)
    smtp.sendmail(sender, receiver, msg.as_string())
    smtp.quit()


client = socket.socket()
host_list = ['192.168.11.128:22','192.168.7.164:443']
for info in host_list:
    ip = re.compile('(.*?):(.*)').search(info).group(1)#(.*?)是从左到右匹配到第一个冒号
    port = re.compile('(.*?):(.*)').search(info).group(2)#(.*)是从冒号开始右边所有
    result = client.connect_ex((ip, int(port)))
    if result != 0:
        sendmail('%s不通' % ip)

paramiko模块

作用:模拟ssh连接主机的,通过paramiko模块连接主机运行bash命令

import paramiko
hostname = '192.168.11.128'
port = 22
username = 'root'
password = '123'
ssh = paramiko.SSHClient() #声明实例
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())#设置丢失主机的密钥策略,即不通过know_hosts文件进行连接
ssh.connect(hostname=hostname,port=port,username=username,password=password)#连接主机
stdin, stdout, stderr = ssh.exec_command("ls -ltr")#执行命令()
print(stdout.read().decode('utf-8'))

运行结果:

上面我们得到了一个命令的结果,那么将命令变为变量,是不是就会变得不一样

import paramiko
hostname = '192.168.11.128'
port = 22
username = 'root'
password = '123'
ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname=hostname,port=port,username=username,password=password)
while True:
    cmd = input('===>:')
    stdin, stdout, stderr = ssh.exec_command(cmd)
    print(stdout.read().decode('utf-8'))

运行结果:

可以看到,我们可以随便输入想要查看的命令,但是没有返回值的命令是不可以的

通过paramiko模块连接主机上传

import paramiko
hostname = '192.168.11.128'
port = 22
username = 'root'
password = '123'
t=paramiko.Transport((hostname, port)) #这个方法就相当于ftp
t.connect(username=username,password=password)#用声明的实例链接ftp
sftp = paramiko.SFTPClient.from_transport(t)sftp.put(r'D:\zzz.txt', '/root/aaa.txt' )#put上传
sftp.close()

运行结果:

通过paramiko模块连接主机下载

import paramiko
hostname = '192.168.11.128'
port = 22
username = 'root'
password = '123'
t=paramiko.Transport((hostname,port))
t.connect(username=username,password=password)
sftp = paramiko.SFTPClient.from_transport(t)
sftp.get('/root/p.py', r'D:\python.py') #get下载
sftp.close()

运行结果:

 pymysql模块

作用:操作数据库的,python3前用的是mysqldb

#pymysql操作数据库
import pymysql
# 打开数据库连接
db = pymysql.connect(host="192.168.11.128", user="root",
                     password="root", db="test1", port=3306)#数据库的用户名和密码

# 使用cursor()方法获取操作游标
cur = db.cursor()

# 1.查询操作
# 编写sql 查询语句  user 对应我的表名
sql = "select students.name,students.age from students"
try:
    cur.execute(sql)  # 执行sql语句
    results = cur.fetchall()  # 获取查询的所有记录
    for i in results:#遍历结果
        print(i)
# except Exception as e: #异常处理(可有可无)
#     raise e
finally:
    db.close()  # 关闭连接

运行结果:

例:批量操作,循环插入1000个数据

db = pymysql.connect(host="192.168.11.128", user="root",
                     password="root", db="test1", port=3306)
cur = db.cursor()
for i in range(1000):
    cur.execute("insert into aaaa values ('bbbb-%s')" % i)
db.commit() #提交
db.close()

运行结果

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!