paramiko模块
基础使用介绍
• SSHClient
– 创建用于连接ssh服务器的实例
• paramiko.AutoAddPolicy
– 设置自动添加主机密钥
• ssh.connect
– 连接ssh服务器
• ssh.exec_comand
– 在ssh服务器上执行指定命令
paramiko实例
• 编写用于实现ssh访问的脚本
– 创建SSHClient实例
– 设置添加主机密钥策略
– 连接ssh服务器
– 执行指定命令
– 在shell命令行中接受用于连接远程服务器的密码以及在远程主机上执行的命令
#安装paramiko模块
[root@room9pc01 paramiko_pkgs]# ls
asn1crypto-0.24.0-py2.py3-none-any.whl
bcrypt-3.1.4-cp36-cp36m-manylinux1_x86_64.whl
cffi-1.11.5-cp36-cp36m-manylinux1_x86_64.whl
cryptography-2.4.2-cp34-abi3-manylinux1_x86_64.whl
idna-2.7-py2.py3-none-any.whl
paramiko-2.4.2-py2.py3-none-any.whl
pyasn1-0.4.4-py2.py3-none-any.whl
pycparser-2.19.tar.gz
PyNaCl-1.3.0-cp34-abi3-manylinux1_x86_64.whl
six-1.11.0-py2.py3-none-any.whl
[root@room9pc01 paramiko_pkgs]# pip3 install *
>>> import paramiko
>>> ssh =paramiko.SSHClient()
>>> ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 当远程主机发来密钥时,接受
>>> ssh.connect('192.168.8.11', username='root', password='123456')
>>> ssh.exec_command('mkdir /tmp/demo')
>>> ssh.close()
[root@room9pc01 ~]# ssh 192.168.8.11
[root@nova01 ~]# ls /tmp/demo/
远程主机执行远程命令(id)
[root@room9pc01 day11]# vim rcmd.py
import paramiko
def rcmd(host, user='root', pwd=None, port=22, command=None):
ssh = paramiko.SSHClient() # 实例化SSHClient
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 设置自动接受密钥
ssh.connect(host, username=user, password=pwd, port=port) # 连接远程服务器
# exec_command的返回值共三项,它们分别是输入、输出、错误,这三项都是类文件对象。那么它们都有read()方法。
stdin, stdout, stderr = ssh.exec_command(command) # 在远程服务器上执行命令
out = stdout.read()
err = stderr.read()
if out: # 如果有输出,则打印在屏幕上
print('[\033[32;1m%s\033[0m] OUT:\n%s' % (host, out.decode()))
if err:
print('[\033[31;1m%s\033[0m] ERROR:\n%s' % (host, err.decode()))
ssh.close() # 关闭连接
if __name__ == '__main__':
rcmd('192.168.8.11', pwd='123456', command='id root; id john')
[root@room9pc01 day11]# python3 rcmd.py
[192.168.8.11] OUT:
uid=0(root) gid=0(root) groups=0(root)
[192.168.8.11] ERROR:
id: john: no such user
批量远程主机修改密码(多线程):
[root@room9pc01 day11]# vim rcmd.py
import paramiko
import threading
import sys
import getpass
import os
def rcmd(host, user='root', pwd=None, port=22, command=None):
ssh = paramiko.SSHClient() # 实例化SSHClient
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 设置自动接受密钥
ssh.connect(host, username=user, password=pwd, port=port) # 连接远程服务器
stdin, stdout, stderr = ssh.exec_command(command) # 在远程服务器上执行命令
out = stdout.read()
err = stderr.read()
if out: # 如果有输出,则打印在屏幕上
print('[\033[32;1m%s\033[0m] OUT:\n%s' % (host, out.decode()))
if err:
print('[\033[31;1m%s\033[0m] ERROR:\n%s' % (host, err.decode()))
ssh.close() # 关闭连接
if __name__ == '__main__':
if len(sys.argv) != 3:
print("Usage: %s ipfile 'command_to_execute'" % sys.argv[0])
exit(1)
if not os.path.isfile(sys.argv[1]):
print('No such file: %s' % sys.argv[1])
exit(2)
ipfile = sys.argv[1]
command = sys.argv[2]
pwd = getpass.getpass() #导入getpass模块后输入密码不回显
with open(ipfile) as fobj:
for line in fobj:
ip = line.strip() # 把一行文本两端的空白字符移除
t = threading.Thread(target=rcmd, args=(ip,), kwargs={'pwd': pwd, 'command': command})
t.start() # target(*args, **kwargs)
[root@room9pc01 day11]# python3 rcmd.py ipaddr.txt 'echo 123456 |passwd --stdin root'
Password: #导入getpass模块后隐形输入密码
[192.168.8.12] OUT:
Changing password for user root.
passwd: all authentication tokens updated successfully.
[192.168.8.11] OUT:
Changing password for user root.
passwd: all authentication tokens updated successfully.
[192.168.8.10] OUT:
Changing password for user root.
passwd: all authentication tokens updated successfully.
##############################################################
SMTP概述
• SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,使用TCP协议25端口
• 它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式
• python的smtplib提供了一种很方便的途径发送电子邮件。它对smtp协议进行了简单的封装SMTP
设置邮件
• 标准邮件需要三个头部信息
– From:发件人
– To:收件人
– Subject:主题
sendmail方法
• Python SMTP 对象使用 sendmail 方法发送邮件
SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options])
• sendmail方法三个必须的参数有:
– 收件人
– 发件人
– 消息主体msg是一个字符串,表示邮件
[root@room9pc01 day11]# vim myemail.py #通过本机发送邮件
from email.mime.text import MIMEText
from email.header import Header
from smtplib import SMTP
#准备邮件
message = MIMEText('Python email test\n', 'plain', 'utf8')
message['From'] = Header('root', 'utf8')
message['To'] = Header('bob', 'utf8')
message['Subject'] = Header('py email', 'utf8')
#发送邮件
smtp = SMTP('127.0.0.1')
smtp.sendmail('root', ['root', 'bob'], message.as_bytes())
############################################################################
[root@room9pc01 day11]# python3 myemail.py
[root@room9pc01 day11]# mail #查看邮件
>N 49 =?utf8?q?root?=@room Sat May 18 14:34 19/645 "py email"
& Message 49:
From root@room9pc01.tedu.cn Sat May 18 14:34:37 2019
Return-Path: <root@room9pc01.tedu.cn>
X-Original-To: root
Delivered-To: root@room9pc01.tedu.cn
Content-Type: text/plain; charset="utf8"
From: root@room9pc01.tedu.cn
To: bob@room9pc01.tedu.cn
Subject: py email
Date: Sat, 18 May 2019 14:34:37 +0800 (CST)
Status: R
Python email test
&
案例:通过互联网服务器发送邮件
[root@room9pc01 day11]# vim send_email.py
from email.mime.text import MIMEText
from email.header import Header
from smtplib import SMTP
import getpass
def send_email(server, passwd, sender, recievres, subject, message):
msg = MIMEText(message, 'plain', 'utf8')
msg['From'] = Header(sender, 'utf8')
msg['To'] = Header(recievres[0], 'utf8')
msg['Subject'] = Header(subject, 'utf8')
smtp = SMTP(server)
# smtp.starttls() # 如果邮件服务器要求安全连接,打开此注释
smtp.login(sender, passwd)
smtp.sendmail(sender, recievres, msg.as_bytes())
if __name__ == '__main__':
server = 'smtp.163.com'
sender = 'liuxe1990@163.com'
passwd = getpass.getpass()
reciveres = ['liuxe1990@163.com']
subject = '163 mail test'
message = 'Hello world!\n Nice to meet you!'
send_email(server, passwd, sender, reciveres, subject, message)
################################################################
JSON概述
• JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式
• 易于人阅读和编写,同时也易于机器解析和生成
• 基于JavaScript Programming Language
• JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java,JavaScript, Perl, Python等)
• 这些特性使JSON成为理想的数据交换语言
JSON结构
• JSON主要有两种结构
– “键/值”对的集合:python中主要对应成字典
– 值的有序列表:在大部分语言中,它被理解为数组
dumps方法
• 对编码后的json对象进行decode解码,得到原始数据,
需要使用的json.loads()函数
>>> import json
>>> adict = {'name': 'bob', 'age': 20}
>>> json.dumps(adict)
'{"name": "bob", "age": 20}'
>>> jdata = json.dumps(adict) # 在网络中发送该字典前,将其转换成json字符串
>>> type(jdata)
<class 'str'>
>>> jdata
'{"name": "bob", "age": 20}'
>>> json.loads(jdata)
{'name': 'bob', 'age': 20}
>>> mydict = json.loads(jdata) # 接收方收到数据后,将json字符串转换回字典
>>> type(mydict)
<class 'dict'>
>>> mydict
{'name': 'bob', 'age': 20}
案例:天气预报查询
- 运行程序时,屏幕将出现你所在城市各区县名字
- 用户指定查询某区县,屏幕上将出现该区县当前的气温、湿度、风向、风速等
- 实况天气获取:http://www.weather.com.cn/data/sk/城市代码.html
- 城市信息获取:http://www.weather.com.cn/data/cityinfo/城市代码.html
- 详细指数获取:http://www.weather.com.cn/data/zs/城市代码.html
城市代码搜索“中国天气网 城市代码”
如北京:http://www.weather.com.cn/data/sk/101010100.html
http://www.weather.com.cn/data/cityinfo/101010100.html
http://www.weather.com.cn/data/zs/101010100.html
>>> import urllib
>>> from urllib import request
>>> bj = request.urlopen('http://www.weather.com.cn/data/sk/101010100.html')
>>> data = bj.read()
>>> data
b'{"weatherinfo":{"city":"\xe5\x8c\x97\xe4\xba\xac","cityid":"101010100","temp":"27.9","WD":"\xe5\x8d\x97\xe9\xa3\x8e","WS":"\xe5\xb0\x8f\xe4\xba\x8e3\xe7\xba\xa7","SD":"28%","AP":"1002hPa","njd":"\xe6\x9a\x82\xe6\x97\xa0\xe5\xae\x9e\xe5\x86\xb5","WSE":"<3","time":"17:55","sm":"2.1","isRadar":"1","Radar":"JC_RADAR_AZ9010_JB"}}'
>>> import json
>>> json.loads(data)
{'weatherinfo': {'city': '北京', 'cityid': '101010100', 'temp': '27.9', 'WD': '南风', 'WS': '小于3级', 'SD': '28%', 'AP': '1002hPa', 'njd': '暂无实况', 'WSE': '<3', 'time': '17:55', 'sm': '2.1', 'isRadar': '1', 'Radar': 'JC_RADAR_AZ9010_JB'}}
############################################################33
requests模块简介
它是一个网络模块,底层采用urllib3。它把很多http的功能定义成了函数,需要某个功能,只要调用函数即可。
• Requests是用Python语言编写的、优雅而简单的HTTP库
• Requests内部采用来urillib3
• Requests使用起来肯定会比urillib3更简单便捷
• Requests需要单独安装
requests特性
• 支持keep-alive的连接池
• 支持通用的域名以及URL地址
• 支持使用cookie
• 支持使用类似浏览器的SSL验证
• 文件上传、下载
GET和POST
• 通过requests发送一个GET请求,需要在URL里请求
的参数可通过params传递
r = requests.get(url="", params={}, headers={}, cookies={})
• 与GET不同的是,POST请求新增了一个可选参数data,需要通过POST请求传递的body里的数据可以通过data传递
- GET: 在浏览器中输入网址访问、点击超链接、通过表单查询
- POST: 一般用于提交隐私的表单数据
r = requests.post(url="", data ={}, params={}, file={}, headers={},
cookies={})
安装request
[root@room9pc01 requests_pkgs]# ls
certifi-2018.10.15-py2.py3-none-any.whl requests-2.20.1-py2.py3-none-any.whl
chardet-3.0.4-py2.py3-none-any.whl urllib3-1.24.1-py2.py3-none-any.whl
idna-2.7-py2.py3-none-any.whl
[root@room9pc01 requests_pkgs]# pip3 install *
纯文本
>>> import requests
>>> r = requests.get('http://www.sogou.com')
>>> r.text
非文本,如图片
>>> r = requests.get('http://k.zol-img.com.cn/sjbbs/7692/a7691515_s.jpg')
>>> with open('/tmp/fengguang.jpg', 'wb') as fobj:
... fobj.write(r.content)
...
118297
[root@room9pc01 day11]# eog /tmp/fengguang.jpg
编码
>>> r = requests.get('http://www.weather.com.cn/data/sk/101010100.html')
>>> r.json() # 乱码
>> r.encoding = 'utf8'
>>> r.encoding
'utf8'
>>> r.json()
{'weatherinfo': {'city': '北京', 'cityid': '101010100', 'temp': '27.9', 'WD': '南风', 'WS': '小于3级', 'SD': '28%', 'AP': '1002hPa', 'njd': '暂无实况', 'WSE': '<3', 'time': '17:55', 'sm': '2.1', 'isRadar': '1', 'Radar': 'JC_RADAR_AZ9010_JB'}}
查快递
查询快递的接口(API应用程序编程接口):http://www.kuaidi100.com/query?type=%s&postid=%s
其中type是快递公司的名称,需要到相应的网站上查询,postid是单号
>>> url = 'http://www.kuaidi100.com/query'
>>> params = {'type': 'zhongtong', 'postid': '75146444783846'}
>>> r = requests.get(url, params= params)
>>> r.json()
{'message': 'ok', 'nu': '75146444783846', 'ischeck': '0', 'condition': '00', 'com': 'zhongtong', 'status': '200', 'state': '0', 'data': [{'time': '2019-05-18 01:37:00', 'ftime': '2019-05-18 01:37:00', 'context': '快件已发往 泉州转运中心', 'location': None}, {'time': '2019-05-18 01:08:52', 'ftime': '2019-05-18 01:08:52', 'context': '快件已到达 深圳转运中心', 'location': None}, {'time': '2019-05-18 00:48:04', 'ftime': '2019-05-18 00:48:04', 'context': '快件已发往 深圳转运中心', 'location': None}, {'time': '2019-05-17 19:29:53', 'ftime': '2019-05-17 19:29:53', 'context': '广东省深圳市华富公司取件人: 深圳市市场部6() 已收件', 'location': None}]}