我尝试使用请求python模块登录到托管交换机(使用静态IPv4),以检索连接到它的设备的mac地址表(然后显然注销)。当使用python 2.7.10时,每次使用登录时都会工作,当使用python3.4.4时,它会失败,但不是每次都会失败。我会说我有1/3的成功机会。
以下示例代码显示了我的计算机上的问题(Mac OS X 10.10.5)。
import sys
import requests
def login():
return requests.post(LOGIN_URL,
headers=HEADERS,
data=LOGIN_DATA,
verify=False,
timeout=10)
def load_table(cookie):
return requests.get(TABLE_URL,
headers=HEADERS,
cookies=cookie)
def logout(cookie):
return requests.post(LOGOUT_URL,
headers=HEADERS,
cookies=cookie,
data=LOGOUT_DATA)
if __name__ == "__main__":
print(sys.version_info)
print("requests version :", requests.__version__)
login_resp = login()
cookies = list()
for req in login_resp.history:
cookies.append(req.cookies)
if len(cookies) > 0:
my_cookie = cookies[0]
print("errormsg position:", login_resp.text.find("errormsg"))
# This line will raise an exception in case of login failure
print("cookie :\n", my_cookie)
my_table = load_table(my_cookie).text
print("mac table :\n", my_table)
logout(my_cookie)
说明:
为清楚起见,我没有复制http变量(LOGIN_URL等)。一切都是正确的,我已经用chrome开发工具和wireshark检查了它。
该代码应该在Python3中使用,因此Python2中的输出将非常难看(请记住它是一个演示代码)。
请求版本相同:2.12.4(最新)。
在Python3中登录失败时将引发NameError
异常,导致响应历史记录将为cookie空。在这种情况下,errormsg="login failed. Authentication failed"
属性中会出现response.text
。
我已经尝试使用Python3.6.0(最新版),但仍然会发生失败。
你们有没有任何线索?该错误是来自python3,请求还是底层操作系统?我是否遗漏了身份验证过程中的某些内容(我对http很新)。
我已尝试使用Python3.4.3并在Windows 7下请求2.12.4,并且每次都失败。
答案 0 :(得分:0)
因此,在使用wireshark逐字节分析请求后,我发现问题来自标头和我提供的数据。在python2.7中,头文件密钥和数据密钥总是以相同的顺序排列,与python3.4相反,这使得我的字典顺序变得混乱。
Here是我在讨论标题排序的请求文档中遗漏的一小部分。
正如笔记一样,这就是我现在定义标题的方式:
HEADERS = OrderedDict()
HEADERS["Host"] = "192.168.0.10"
HEADERS["Connection"] = "keep-alive"
HEADERS["Accept-Encoding"] = "gzip, deflate"
HEADERS["Accept"] = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
HEADERS["User-Agent"] = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36"
HEADERS["Accept-Language"] = "en-US,en;q=0.8,fr;q=0.6"
HEADERS["Referer"] = "http://192.168.0.10/"
HEADERS["Content-type"] = "application/x-www-form-urlencoded"
LOGIN_DATA = OrderedDict()
LOGIN_DATA["pwd_password"] = "admin"
LOGIN_DATA["sel_username"] = "admin"
LOGIN_DATA["btnLogin"] = "Login"
以前的代码现在连接每次 !!哈利路亚!
如果有人知道为什么我需要这样做,我会很高兴知道!