Python:请求会话登录Cookies

5

我的意图是使用Python脚本登录网站并访问受保护的图像。我已经在浏览器中获得了合法且正常的访问权限。

以下是我目前拥有的内容:

import requests

s = requests.Session()

s.get('*domain*')

r_login  =s.post('*domain*/user.php', headers={'cmd': 'login', 'loginname': '***', 'password': '***' })

print (s.cookies)
print (r_login.status_code)

r_img = s.get('*domain*/*protectedimage*.jpg')
print (r_img.status_code)
print (r.cookies)

print (s.cookies['PHPSESSID'])

输出:

<<class 'requests.cookies.RequestsCookieJar'>[<Cookie PHPSESSID=664b0842085b847a04d415a22e013ad8 for *domain*/>]>
200
403
<<class 'requests.cookies.RequestsCookieJar'>[]>
664b0842085b847a04d415a22e013ad8

我确信我能够成功登录,因为我曾经在登录后下载了html文件,而且它是以已登录的形式存在的。但问题是似乎我的PHPSESSID cookie没有传递,所以我收到了一个403错误。但我明确地知道它在我的会话中。我也尝试将cookie手动添加到我的"r_img"行中,但没有任何区别,我仍然得到一个空的CookieJar和一个403错误。只使用请求模块是否可能实现这一点?我有没有忽略什么?请原谅我对HTTP请求不太熟悉。

为了清晰起见,我正在使用Python 3.4。


很可能你不应该设置cookies,而是使用POST数据。Cookies应该由你所提交的服务器来设置。请参考我的回答。 - data
2个回答

5
您正在将您的表单数据作为HTTP标头传递。POST登录表单应该将表单元素作为"data"参数发送:
r_login = s.post('*domain*/user.php', 
                 data={'cmd': 'login', 'loginname': '***', 'password': '***' })

请检查返回的内容,不仅限于状态码。虽然服务器已接受了您的POST请求(200 OK),但由于未提交登录信息,body 很可能会告诉您类似“登录失败,请重试”的信息。
当您请求图像时,服务器很可能会再次清除 cookie,因为它不是有效的登录会话。403响应很可能包含一个 Set-Cookie 头,其中包含一个过去的日期以清除 PHPSESSID

非常好用!非常感谢。我之前不知道关于post方法的事情。我所要做的就是将“headers”改为“data”。现在我可以下载我的图片了。file = open('myimg.jpg', 'wb') file.write(r_img.content) file.close() - Tigris
1
@Tigris:如果要下载(较大的)图像,请考虑流式传输下载,以避免首先将整个下载存储在内存中。请参见如何使用requests下载图像 - Martijn Pieters
再次感谢。幸运的是,我只需要获取一些小图像。 :) - Tigris

3

试着按照以下方式进行:

根据python-requests文档:

payload = {'cmd': 'login', 'loginname': '***', 'password': '***'}
url = '*domain*/user.php'
s.post(url, data=payload)

谢谢,更严格地遵循文档可能是一个解决方案。 - Tigris
@Tigris,您能否详细说明为什么您接受了Martjin的答案而不是我的?我们的代码完全相同,而且我比他先回答了5分钟。 - data
4
是的,非常抱歉在决定选择哪个答案时我没有考虑时间,我都将你的回答标记为有用,但是Martjin还为我提供了详细的解释。我真的需要知道一个POST方法必须发送到“data”参数中,这点解决了我的问题。 - Tigris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接