此模块用于简化paramiko与网络设备之间的ssh连接,可在windows与Unix平台使用
一.安装模块
#前提准备模块:
Paramiko >= 2.4.1
scp >= 0.10.0
pyyaml
pyserial
textfsm
#安装netmiko
pip install netmiko
from netmiko import ConnectHandler
'''
关于netmiko的使用,建议查看官网的说明,
简单的show命令的话,用以下代码即可,注意的是device_type
内置常用的有有以下 请留意左侧的key值,是支持的设备系列。
CLASS_MAPPER_BASE = {
'a10': A10SSH,
'accedian': AccedianSSH,
'alcatel_aos': AlcatelAosSSH,
'alcatel_sros': AlcatelSrosSSH,
'apresia_aeos': ApresiaAeosSSH,
'arista_eos': AristaSSH,
'aruba_os': ArubaSSH,
'avaya_ers': AvayaErsSSH,
'avaya_vsp': AvayaVspSSH,
'brocade_fastiron': RuckusFastironSSH,
'brocade_netiron': BrocadeNetironSSH,
'brocade_nos': BrocadeNosSSH,
'brocade_vdx': BrocadeNosSSH,
'brocade_vyos': VyOSSSH,
'checkpoint_gaia': CheckPointGaiaSSH,
'calix_b6': CalixB6SSH,
'ciena_saos': CienaSaosSSH,
'cisco_asa': CiscoAsaSSH,
'cisco_ios': CiscoIosSSH,
'cisco_nxos': CiscoNxosSSH,
'cisco_s300': CiscoS300SSH,
'cisco_tp': CiscoTpTcCeSSH,
'cisco_wlc': CiscoWlcSSH,
'cisco_xe': CiscoIosSSH,
'cisco_xr': CiscoXrSSH,
'coriant': CoriantSSH,
'dell_force10': DellForce10SSH,
'dell_os10': DellOS10SSH,
'dell_powerconnect': DellPowerConnectSSH,
'dell_isilon': DellIsilonSSH,
'eltex': EltexSSH,
'enterasys': EnterasysSSH,
'extreme': ExtremeSSH,
'extreme_wing': ExtremeWingSSH,
'f5_ltm': F5LtmSSH,
'fortinet': FortinetSSH,
'generic_termserver': TerminalServerSSH,
'hp_comware': HPComwareSSH,
'hp_procurve': HPProcurveSSH,
'huawei': HuaweiSSH,
'huawei_vrpv8': HuaweiVrpv8SSH,
'juniper': JuniperSSH,
'juniper_junos': JuniperSSH,
'linux': LinuxSSH,
'mellanox': MellanoxSSH,
'mrv_optiswitch': MrvOptiswitchSSH,
'netapp_cdot': NetAppcDotSSH,
'netscaler': NetscalerSSH,
'ovs_linux': OvsLinuxSSH,
'paloalto_panos': PaloAltoPanosSSH,
'pluribus': PluribusSSH,
'quanta_mesh': QuantaMeshSSH,
'ruckus_fastiron': RuckusFastironSSH,
'ubiquiti_edge': UbiquitiEdgeSSH,
'ubiquiti_edgeswitch': UbiquitiEdgeSSH,
'vyatta_vyos': VyOSSSH,
'vyos': VyOSSSH,
}
二.执行查看命令:show ip int brief
from netmiko import ConnectHandler
cisco = {
'device_type':'cisco_ios',
'host':'ip地址',
'username':'用户名',
'password':'密码'
}
net_connect = ConnectHandler(**cisco)
##或者
# net_connect = ConnectHandler(device_type='cisco_ios',host='IP地址',username='用户名',password='密码')
#找到目前所在视图
current_view = net_connect.find_prompt()print(current_view)
#执行命令,返回结果为字符串,赋值给output
output = net_connect.send_command('show ip int brief')
print(output)
# 此为在windows里如果\n不能显示回车,则进行如下语句格式化
# o_list = output.split("\n")
# for line in o_list:
# print(line)
----------------------------------
当然你可能不知道类型,也可以试试自动匹配,但不推荐:
from netmiko import SSHDetect, Netmiko
device = {'device_type': 'autodetect',
'host': 'XXX',
'port': 'XXX',
'username': 'root',
'password': 'XXX', }
guesser = SSHDetect(**device)
best_match = guesser.autodetect()
print('best_match is:{}'.format(best_match))
print('all guessers is:{}'.format(guesser.potential_matches))
device['device_type'] = best_match
connection = Netmiko(**device)
# 获取回显的前缀,提示符,prompt。
print('prompt is :{}'.format(connection.find_prompt())
三.执行配置命令:手动关闭接口G1/0/22
from netmiko import ConnectHandler
cisco = {
'device_type':'cisco_ios',
'host':'ip地址',
'username':'用户名',
'password':'密码'
}
net_connect = ConnectHandler(**cisco)
#或者
# net_connect = ConnectHandler(device_type='cisco_ios',host='IP地址',username='用户名',password='密码')
#要配置的命令
config_commands = ['interface GigabitEthernet1/0/22','shutdown']
#提交要配置的命令,input为提交的真实内容
input = net_connect.send_config_set(config_commands)
#验证shutdown是否执行成功
output = net_connect.send_command('show run inter gi1/0/22')
print(output)
# 此为在windows里如果\n不能显示回车,则进行如下语句格式化
# o_list = output.split("\n")
# for line in o_list:
# print(line)
四.常用方法
---------------------------------------------------------------------------------------------------------------------
此模块可以用来和像 ssh、ftp、passwd、telnet 等命令行程序进行自动交互。是 Expect 语言的一个 Python 实现,用来启动子程序,并使用正则表达式对程序输出做出特定响应。
整体来说大致的流程包括:
pexpect 的使用说来说去,就是围绕3个关键命令做操作:
第一步只需要做一次,但在程序中会不停的循环第二、三步来一步一步的完成整个工作。掌握这个概念之后 pexpect 的使用就很容易了。
process = pexpect.spawn('ftp sw-tftp' , timeout=60)
注意: spawn() ,或者说 pexpect 并不会转译任何特殊字符 比如 | * 字符在Linux的shell中有特殊含义,如果在 linux 系统中想使用这些符号的正确含义就必须加上 shell 来运行,这是很容易犯的一个错误。
正确的方式:process = pexpect.spawn('/bin/bash –c "ls –l | grep LOG > log_list.txt"')
返回 0 表示匹配到了所需的关键字,如果后面的匹配关键字是一个列表的话,会返回列表中第几个关键字,从 0 开始计算。
用来向程序发送指定的字符串,比如:
process.expect("ftp>")
process.send("by\n")
sendline() 和 send() 唯一的区别就是在发送的字符串后面加上了回车换行符。
sendcontrol() 向子程序发送控制字符,比如你要向子程序发送 ctrl+G,那么就这样写:process.sendcontrol('g')
--------------------------------------------------------------------------------------------------------------------
可以用来完成浏览器自动化相关的操作(行为动作),浏览器就会自动触发相关的事件
浏览器的驱动程序(谷歌浏览器)
http://chromedriver.storage.googleapis.com/index.html
实例化一个浏览器对象
- 编写基于浏览器自动化的操作代码
- 发起请求:get(url)
- 标签定位:find系列的方法
- 标签交互:send_keys('xxx')
- 执行js程序:excute_script('jsCode')
- 前进,后退:back(),forward()
- 关闭浏览器:quit()
- selenium处理iframe
- 如果定位的标签存在于iframe标签之中,则必须使用switch_to.frame(id)
- 动作链(拖动):from selenium.webdriver import ActionChains
- 实例化一个动作链对象:action = ActionChains(bro)
- click_and_hold(div):长按且点击操作
- move_by_offset(x,y)
- perform()让动作链立即执行
- action.release()释放动作链对象
pip install selenium
下载对应浏览器的驱动程序
https://npm.taobao.org/
https://chromedriver.storage.googleapis.com/index.html
执行js实现滚轮向下
//移动到页面最底部(如果是动态加载的数据及第一次加载完成的地方):
js = "window.scrollTo(0,document.body.scrollHeight)"
定位标签,向标签里写参数
tag_input = bro.find_element_by_id('kw')
tag_input.send_keys('人民币')
截屏
bro.save_screenshot('1.png')
网页的前进和后退
bro.back() 后退
bro.forward() 前进
#谷歌无头浏览器
from selenium import webdriver
from time import sleep
from selenium.webdriver.chrome.options import Options
# 创建一个参数对象,用来控制chrome以无界面模式打开
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
bro = webdriver.Chrome(executable_path='./chromedriver.exe',options=chrome_options)
bro.get('https://www.baidu.com')
sleep(2)
bro.save_screenshot('1.png')
#标签定位
tag_input = bro.find_element_by_id('kw')
tag_input.send_keys('人民币')
sleep(2)
btn = bro.find_element_by_id('su')
btn.click()
sleep(2)
print(bro.page_source)
bro.quit()
#动作链
from selenium import webdriver
from time import sleep
from selenium.webdriver import ChromeOptions
from selenium.webdriver import ActionChains
option = ChromeOptions()
option.add_experimental_option('excludeSwitches', ['enable-automation'])
bro = webdriver.Chrome(executable_path='./chromedriver.exe',options=option)
url = 'https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable'
bro.get(url=url)
#如果定位的标签存在于iframe标签之中,则必须经过switch_to操作在进行标签定位
bro.switch_to.frame('iframeResult')
source_tag = bro.find_element_by_id('draggable')
taget_tag = bro.find_element_by_id('droppable')
#创建一个动作连的对象
action = ActionChains(bro)
action.drag_and_drop(source_tag,taget_tag)
action.perform()
sleep(3)
# bro.quit()
附:
#selenium有以下定位方式
driver.find_element_by_id(‘id’)
driver.find_element_by_xpath('xpath')
driver.find_element_by_link_text('link_text')
driver.find_element_by_partial_link_text('partial_link_text')
driver.find_element_by_name('name')
driver.find_element_by_tag_name('tag_name')
driver.find_element_by_class_name('class_name')
driver.find_element_by_css_selector('css_selector')
实例代码:
from selenium import webdriver
#from selenium.webdriver.common.by import By
from lxml import etree
from time import sleep
#后面是你的浏览器驱动位置,记得前面加r'','r'是防止字符转义的,发起请求
bro = webdriver.Chrome(r'./chromedriver')
bro.get("http://XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
#满屏
bro.maximize_window()
#登录操作
userName_tag = bro.find_element_by_name('j_username')
password_tag = bro.find_element_by_name('j_password')
sleep(1)
userName_tag.send_keys('XXXXXXXXXXXXXXXXXXXXXXXX')
sleep(1)
password_tag.send_keys('XXXXXXXXXXXXXXXXXXXXXXXX')
sleep(1)
btn = bro.find_element_by_name('提交')
btn.click()
sleep(5)
#点击链接
bro.find_elements_by_link_text("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")[0].click()
sleep(5)
#浏览器跳转页获取当前浏览器的所有标签页
handles = bro.window_handles
#print(handles)
#定位到第二个标签页
bro.switch_to_window(handles[1])
#定位第5个iframe
iframe = bro.find_elements_by_tag_name('iframe')[4]
bro.switch_to.frame(iframe)
#表格内容输出,进一步定位到表格内容所在的td节点,存储为list
td_content = bro.find_elements_by_tag_name("td")
lst = []
for td in td_content:
lst.append(td.text)
con = 0
conut = 0
while (con<5):
print('源:'+lst[5+conut]+' 目的:'+lst[6+conut]+' 应用:'+lst[7+conut]+' 流量:'+lst[8+conut])
con = con+1
conut = conut+4
#单独取某元素的内容
Test_1 = bro.find_elements_by_xpath('/html/body/table[2]/tbody/tr[2]/td[1]')[0]
print('头号:'+Test_1.get_attribute('textContent'))
sleep(3)
#关闭实例
bro.quit()
注:
1. driver对象的常用属性和方法
在使用selenium过程中,实例化driver对象后,driver对象有一些常用的属性和方法
driver.page_source 当前标签页浏览器渲染之后的网页源代码
driver.current_url 当前标签页的url
driver.close() 关闭当前标签页,如果只有一个标签页则关闭整个浏览器
driver.quit() 关闭浏览器
driver.forward() 页面前进
driver.back() 页面后退
driver.screen_shot(img_name) 页面截图
2. driver对象定位标签元素获取标签对象的方法
在selenium中可以通过多种方式来定位标签,返回标签元素对象
find_element_by_id (返回一个元素)
find_element(s)_by_class_name (根据类名获取元素列表)
find_element(s)_by_name (根据标签的name属性值返回包含标签对象元素的列表)
find_element(s)_by_xpath (返回一个包含元素的列表)
find_element(s)_by_link_text (根据连接文本获取元素列表)
find_element(s)_by_partial_link_text (根据链接包含的文本获取元素列表)
find_element(s)_by_tag_name (根据标签名获取元素列表)
find_element(s)_by_css_selector (根据css选择器来获取元素列表)
---------------------------------------------------------------------------------------------------------------------------
Request支持HTTP连接保持和连接池,支持使用cookie保持会话,支持文件上传,支持自动响应内容的编码,支持国际化的URL和POST数据自动编码,会自动实现持久连接keep-alive。
pip install requests
requests.get(url=url, headers=headers, params=params)
# coding:utf-8
import requests
# 请求url
url = "http://httpbin.org/get"
# 请求头
headers = {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"User-Agent": "python-requests/2.9.1",
}
# 查询字符串
params = {'name': 'Jack', 'age': '24'}
r = requests.get(url=url, headers=headers, params=params)
print r.status_code # 获取响应状态码
print r.content # 获取响应消息
if __name__ == "__main__":
pass
requests.post(url=url, headers=headers, data=params)
# coding:utf-8
import requests
# 请求url
url = "http://httpbin.org/post"
# 请求头
headers = {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"User-Agent": "python-requests/2.9.1",
}
# 查询字符串
params = {'name': 'Jack', 'age': '24'}
r = requests.post(url=url, headers=headers, data=params)
print r.status_code # 获取响应状态码
print r.content # 获取响应消息
if __name__ == "__main__":
pass
requests.post(url=url, headers=headers, data=params, files=files)
# coding:utf-8
import requests
# 请求url
url = "http://httpbin.org/post"
# 请求头
headers = {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"User-Agent": "python/2.9.1",
}
# 查询字符串
params = {'name': 'Jack', 'age': '24'}
# 文件
files = {'upload_img': ('report.xlsx', open('report.xlsx', 'rb'), 'image/png')}
r = requests.post(url=url, data=params, headers=headers, files=files)
print r.status_code # 获取响应状态码
print r.content # 获取响应消息
if __name__ == "__main__":
pass
# HTTP请求类型
# get类型
r = requests.get('https://github.com/timeline.json')
# post类型
r = requests.post("http://m.ctrip.com/post")
# put类型
r = requests.put("http://m.ctrip.com/put")
# delete类型
r = requests.delete("http://m.ctrip.com/delete")
# head类型
r = requests.head("http://m.ctrip.com/head")
# options类型
r = requests.options("http://m.ctrip.com/get")
# 获取响应内容
print(r.content) #以字节的方式去显示,中文显示为字符
print(r.text) #以文本的方式去显示
#URL传递参数
payload = {'keyword': '香港', 'salecityid': '2'}
r = requests.get("http://m.ctrip.com/webapp/tourvisa/visa_list", params=payload)
print(r.url) #示例为http://m.ctrip.com/webapp/tourvisa/visa_list?salecityid=2&keyword=香港
#获取/修改网页编码
r = requests.get('https://github.com/timeline.json')
print (r.encoding)
#json处理
r = requests.get('https://github.com/timeline.json')
print(r.json()) # 需要先import json
# 定制请求头
url = 'http://m.ctrip.com'
headers = {'User-Agent' : 'Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 4 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19'}
r = requests.post(url, headers=headers)
print (r.request.headers)
#复杂post请求
url = 'http://m.ctrip.com'
payload = {'some': 'data'}
r = requests.post(url, data=json.dumps(payload)) #如果传递的payload是string而不是dict,需要先调用dumps方法格式化一下
# post多部分编码文件
url = 'http://m.ctrip.com'
files = {'file': open('report.xls', 'rb')}
r = requests.post(url, files=files)
# 响应状态码
r = requests.get('http://m.ctrip.com')
print(r.status_code)
# 响应头
r = requests.get('http://m.ctrip.com')
print (r.headers)
print (r.headers['Content-Type'])
print (r.headers.get('content-type')) #访问响应头部分内容的两种方式
# Cookies
url = 'http://example.com/some/cookie/setting/url'
r = requests.get(url)
r.cookies['example_cookie_name'] #读取cookies
url = 'http://m.ctrip.com/cookies'
cookies = dict(cookies_are='working')
r = requests.get(url, cookies=cookies) #发送cookies
#设置超时时间
r = requests.get('http://m.ctrip.com', timeout=0.001)
#设置访问代理
proxies = {
"http": "http://10.10.1.10:3128",
"https": "http://10.10.1.100:4444",
}
r = requests.get('http://m.ctrip.com', proxies=proxies)
#如果代理需要用户名和密码,则需要这样:
proxies = {
"http": "http://user:[email protected]:3128/",
}
参考:
Python—requests模块详解 - 小L小 - 博客园