Python中使用cookies进行身份验证的HTTP POST和GET请求

14
我正在尝试创建一个Python程序,使用我的ID和密码登录我的大学网站。这是登录的正式页面:https://webapp.pucrs.br/consulta/
你可能会注意到,两个字段被命名为pr1和pr2。该页面使用POST方法发送数据。同时,在加载页面时会下载一个cookie,它是一个包含随机值的JSESSIONID,据我了解,你必须在POST方法的头部返回它以验证登录信息。
我编写了以下代码,但是GET方法返回的页面显示“未初始化会话”,很可能是因为没有正确地发送cookie。
from urllib2 import Request, build_opener, HTTPCookieProcessor, HTTPHandler
import httplib, urllib, cookielib, Cookie, os

conn = httplib.HTTPConnection('webapp.pucrs.br')

#COOKIE FINDER
cj = cookielib.CookieJar()
opener = build_opener(HTTPCookieProcessor(cj),HTTPHandler())
req = Request('http://webapp.pucrs.br/consulta/principal.jsp')
f = opener.open(req)
html = f.read()
for cookie in cj:
    c = cookie
#FIM COOKIE FINDER

params = urllib.urlencode ({'pr1':111049631, 'pr2':<pass>})
headers = {"Content-type":"text/html",
           "Set-Cookie" : "JSESSIONID=70E78D6970373C07A81302C7CF800349"}
            # I couldn't set the value automaticaly here, the cookie object can't be converted to string, so I change this value on every session to the new cookie's value. Any solutions?

conn.request ("POST", "/consulta/servlet/consulta.aluno.ValidaAluno",params, headers) # Validation page
resp = conn.getresponse()

temp = conn.request("GET","/consulta/servlet/consulta.aluno.Publicacoes") # desired content page
resp = conn.getresponse()

print resp.read()

我应该把这个cookie放在哪里,才能进行登录认证?

5个回答

24

我建议使用requests库。 文档非常好,并且代码最终比使用urllib*更加整洁。

$ pip install requests

使用一个会话(参见Piotr的评论),该会话可以自行处理cookies,结果如下所示

import requests
url_0 = "http://webapp.pucrs.br/consulta/principal.jsp"
url = "https://webapp.pucrs.br/consulta/servlet/consulta.aluno.ValidaAluno"
data = {"pr1": "123456789", "pr2": "1234"}

s = requests.session()
s.get(url_0)
r = s.post(url, data)

看起来它工作得很好,因为当我使用pr1 123456789和您的用户号时,我都收到了“Usuario inexistente”和“Sehna inválida”的通知。


3
您可以使用会话(session)自动处理Cookies。从 文档 中得知:Session对象允许您在请求之间保留某些参数,并且还会跨所有由该Session实例发出的请求保留Cookies。 - Piotr Dobrogost
@PiotrDobrogost 很酷,谢谢!而且代码看起来更好。 - jorgeca

7
你需要使用同一个“opener”来处理你的所有请求,它会自动处理cookies。以下是我最近写的一段内容的摘录。
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookielib.CookieJar()))

# then for all requests

if postData:     
    pData =  urllib.urlencode(postData)
else:
    pData = None

httpReq = urllib2.Request(url, pData, self._headers)
page =  opener.open(httpReq)

5
将MatthieuW的答案转换为Python 3,结果如下。
import urllib, http.cookiejar

opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(http.cookiejar.CookieJar()))
# then for all requests

if postData:     
    pData =  urllib.parse.urlencode(postData)
else:
    pData = None

httpReq = urllib.request.Request(url, pData)
page =  opener.open(httpReq)

3

urllib不太好用,建议使用requests!

from requests import Request, Session

url = "https://webapp.pucrs.br/consulta/principal.jsp"
s = requests.Session()

p = dict(pb1 = 'dd', pb2 = 'cc')
r = s.get(url, params = p) 
# use the cert=/path/to/certificate.pem if you need it
# elsewhere use verify = False to bypass ssl verification

c = r.cookies

# Then send back a response using those same cookies

r = requests.get(other_url, cookies = c, verify = False)

1

我建议您使用mechanize,它可以自动处理会话/cookie/登录,此外还提供类似于urllib的API和表单填充功能,因此您不必烦恼正确的POST请求,因为它由mechanize构建。


我已经安装了它,但它一直提示没有安装名为 mechanize 的模块。有点奇怪,但我会继续尝试。它也处理 cookies 吗?因为那是我的唯一问题。 - Lucas C. Feijo
是的,它处理了cookies!也许你安装的是错误的Python版本。 - dav1d

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