post请求在python3 +中失败(有时),从不在python2.7中

时间:2017-01-17 10:09:27

标签: python macos python-2.7 python-3.x python-requests

我尝试使用请求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,并且每次都失败。

1 个答案:

答案 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"  

以前的代码现在连接每次 !!哈利路亚!

如果有人知道为什么我需要这样做,我会很高兴知道!