使用Python请求进行Cookie认证
我正在尝试用Python的requests
库模拟用户在网站上的操作。为了做到这一点,我需要在请求中包含用户名和密码的认证信息,同时还需要在请求头中添加一些作为Cookie的NVP(名称-值对)。
为了获取这些NVP,我首先发送一个测试请求,服务器会返回给我一些Cookie。我从这些Cookie中获取所需的值,然后用这些值来发送真正的请求。
但是,真正的请求没有成功,服务器提示我没有登录。不过,如果我使用浏览器中的Cookie值,那个请求就能成功。
我用来获取JSESSIONID、glide_user和glide_user_session参数的测试请求是:
response = requests.get('http://example.com/make_dummy_get',auth=('username','pasword'))
cookie_params = response.cookies.items()
下面是实际的请求:
headers = {
'Host': 'example.com'
,'Connection': 'keep-alive'
,'Content-Length': 113
,'Cache-Control': 'max-age=0'
,'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'
,'Origin': 'example.com'
,'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36'
,'Content-Type': 'application/x-www-form-urlencoded'
,'Referer': 'www.example.com/asdas/'
,'Accept-Encoding': 'gzip,deflate,sdch'
,'Accept-Language': 'en-US,en;q=0.8'
,'Cookie': 'JSESSIONID=B6F7371A11825472CAB0366A4DCDD8EFB; glide_user="SC:Z3Vlc3Q=:b890b38b7f000001121dbe81a08c413ca5"; glide_user_session="SC:Z3Vlc3Q=:b890b38b7f000001121dbe81a08c413ca5"'
}
form_data = {
'param1': 'value1'
,'param2': 'value2'
,'param3': 'value3'
}
res = requests.post('http://example.com/make_post_request',auth=('username','pasword'),data=form_data,headers = headers)
看起来我发送的测试请求创建的会话因为某种原因被关闭了,因此第二个请求被拒绝,HTML响应提示我必须登录才能访问请求的资源。
我用Java的Apache HttpClient做了同样的事情,结果也遇到了同样的问题。我在这里缺少了什么,导致请求在没有登录或认证问题的情况下无法成功呢?
1 个回答
首先,你应该使用一个来自requests库的Session
对象。这个对象会帮你管理cookies(也就是小数据块),并为你准备好这些数据,所以你不需要自己去创建cookie的头信息。
s = requests.Session()
s.get('http://example.com/make_dummy_get',auth=('username','pasword'))
print(s.cookies)
接下来,我强烈建议你停止设置以下这些头信息:
Host
Content-Length
Content-Type
Cookie
这四个头信息都会由requests
自动生成。Cookie
头信息会使用Session
中的CookieJar
来生成。而Content-Length
和Content-Type
则是在requests
准备请求内容时计算出来的。
另外,如果你是想用cookies来进行身份验证,服务器可能会感到困惑,因为在你的第二个请求中你还传递了auth=('username', 'password')
。这会生成一个授权头信息,所以你同时发送了Cookie
头和Authorization
头。服务器可能会觉得这很可疑,因此拒绝接受你的请求作为有效的身份验证。