用Python自動登陸TP-LINK路由器,獲取信息,重啓等操做python
思路:想獲取TP-LINK裏面的全部信息,必須首先登陸,而後提交相應的操做(好比重啓)json
一、 作任何操做,首先得登陸到路由器
界面上面默認只有一個「密碼」輸入框,這裏隨便輸入一個123密碼發現,TP-LINK提交後的密碼爲加密後的,分析js就能夠看到加密方法(下面會附上代碼),再把加密後的密碼提交就搞定啦
路由器登陸post信息截圖(TP-LINK關掉了頁面右鍵功能,能夠手動打開瀏覽器的開發者工具,網絡部分查看):
瀏覽器
附上Python實現登陸的方法網絡
#!/usr/bin/env python # -*- coding:utf8 -*- ''' Author : mafei Date : 18/1/20 ''' import requests import json # 加密提交後的密碼,能夠把本身的密碼提交到這個方法,再跟TP-LINK頁面中實際提交的密碼值作比對 def encrypt_pwd(password): input1 = "RDpbLfCPsJZ7fiv" input3 = "yLwVl0zKqws7LgKPRQ84Mdt708T1qQ3Ha7xv3H7NyU84p21BriUWBU43odz3iP4rBL3cD02KZciXTysVXiV8ngg6vL48rPJyAUw0HurW20xqxv9aYb4M9wK1Ae0wlro510qXeU07kV57fQMc8L6aLgMLwygtc0F10a0Dg70TOoouyFhdysuRMO51yY5ZlOZZLEal1h0t9YQW0Ko7oBwmCAHoic4HYbUyVeU3sfQ1xtXcPcf1aT303wAQhv66qzW" len1 = len(input1) len2 = len(password) dictionary = input3 lenDict = len(dictionary) output = '' if len1 > len2: length = len1 else: length = len2 index = 0 while index < length: # 十六進制數 0xBB 的十進制爲 187 cl = 187 cr = 187 if index >= len1: # ord() 函數返回字符的整數表示 cr = ord(password[index]) elif index >= len2: cl = ord(input1[index]) else: cl = ord(input1[index]) cr = ord(password[index]) index += 1 # chr() 函數返回整數對應的字符 output = output + chr(ord(dictionary[cl ^ cr]) % lenDict) return output # 提交登陸請求的方法 def login(password=''): encrypt_password = encrypt_pwd(password) url = 'http://192.168.1.1/' headers = {'Content-Type': 'application/json; charset=UTF-8'} payload = '{"method":"do","login":{"password":"%s"}}' % encrypt_password response = requests.post(url, data=payload, headers=headers) response_body = json.loads(response.text) return response_body if __name__ == '__main__': print(login(password='xxx')) # 返回的數據樣例,error_code爲0表示登陸成功,stok是動態生成的key {u'error_code': 0, u'stok': u'xxx'}
二、 獲取登陸以後的設備信息
先觀察規律會發現,每次TP-LINK提交到後臺的URL中都有一個stok的變量,是TP-LINK生成的動態key,每次登錄都會從新生成一個,這個stok在上一步登錄以後咱們已經獲取到了,後面就直接提交相應的json請求就能夠了,到此已經已經所有搞定app
def get_all_host(password): stok = login(password).get('stok') payload = '{"hosts_info":{"table":"host_info"},"method":"get"}' headers = {'Content-Type': 'application/json; charset=UTF-8'} url = '%sstok=%s/ds' % ('http://192.168.1.1/', stok) response = requests.post(url, data=payload, headers=headers) return response.text if __name__ == '__main__': print(get_all_host(password='xxx')) # 返回的樣例數據 # { "hosts_info": { "host_info": [ { "host_info_1": { "mac": "4c-32-75-29-5a-f3", "type": "1", "blocked": "0", "ip": "192.168.1.104", "hostname": "mafeiMBP", "up_speed": "3487", "down_speed": "5733", "up_limit": "0", "down_limit": "0", "cfg_valid": "0", "is_cur_host": "1", "ssid": "", "wifi_mode": "0", "plan_rule": [ ] } }, { "host_info_4": { "mac": "48-d2-24-ed-51-a4", "type": "1", "blocked": "0", "ip": "192.168.1.103", "hostname": "Lenovo%2DPC", "up_speed": "5733", "down_speed": "1975", "up_limit": "0", "down_limit": "0", "cfg_valid": "0", "is_cur_host": "0", "ssid": "", "wifi_mode": "0", "plan_rule": [ ] } }, { "host_info_2": { "mac": "90-8d-6c-0a-a6-8d", "type": "1", "blocked": "0", "ip": "192.168.1.101", "hostname": "iPad%2D2", "up_speed": "0", "down_speed": "0", "up_limit": "0", "down_limit": "0", "cfg_valid": "0", "is_cur_host": "0", "ssid": "", "wifi_mode": "0", "plan_rule": [ ] } } ] }, "error_code": 0 }
這裏附上完整源代碼ide
#!/usr/bin/env python # -*- coding:utf8 -*- ''' Author : mafei Date : 18/1/20 ''' import requests import json class LoginTpLink(object): def __init__(self): self.password = 'xxx' self.stok = self.login(self.password) # 初始化類的時候就自動登陸,獲取到stok(動態key) # 加密密碼的方法 def encrypt_pwd(self, password): input1 = "RDpbLfCPsJZ7fiv" input3 = "yLwVl0zKqws7LgKPRQ84Mdt708T1qQ3Ha7xv3H7NyU84p21BriUWBU43odz3iP4rBL3cD02KZciXTysVXiV8ngg6vL48rPJyAUw0HurW20xqxv9aYb4M9wK1Ae0wlro510qXeU07kV57fQMc8L6aLgMLwygtc0F10a0Dg70TOoouyFhdysuRMO51yY5ZlOZZLEal1h0t9YQW0Ko7oBwmCAHoic4HYbUyVeU3sfQ1xtXcPcf1aT303wAQhv66qzW" len1 = len(input1) len2 = len(password) dictionary = input3 lenDict = len(dictionary) output = '' if len1 > len2: length = len1 else: length = len2 index = 0 while index < length: # 十六進制數 0xBB 的十進制爲 187 cl = 187 cr = 187 if index >= len1: # ord() 函數返回字符的整數表示 cr = ord(password[index]) elif index >= len2: cl = ord(input1[index]) else: cl = ord(input1[index]) cr = ord(password[index]) index += 1 # chr() 函數返回整數對應的字符 output = output + chr(ord(dictionary[cl ^ cr]) % lenDict) return output # 登陸方法 def login(self, password=''): encryptPwd = self.encrypt_pwd(password) url = 'http://192.168.1.1/' headers = {'Content-Type': 'application/json; charset=UTF-8'} payload = '{"method":"do","login":{"password":"%s"}}' % encryptPwd response = requests.post(url, data=payload, headers=headers) stok = json.loads(response.text)['stok'] return stok # 獲取全部主機信息的方法 def all_host_info(self): payload = '{"hosts_info":{"table":"host_info"},"method":"get"}' response = self.post_tp_link(payload) return response.text # 重啓路由器的方法 def reboot(self): payload = '{"system":{"reboot":null},"method":"do"}' response = self.post_tp_link(payload) return response.text # 爲了通用,封裝的post方法 def post_tp_link(self, payload): headers = {'Content-Type': 'application/json; charset=UTF-8'} url = '%sstok=%s/ds' % ('http://192.168.1.1/', self.stok) response = requests.post(url, data=payload, headers=headers) return response if __name__ == '__main__': login_tp_link = LoginTpLink() result = login_tp_link.reboot() import pprint pprint.pprint(json.loads(result))