由于 HTTP 请求是无状态的,因此该站点使用 JSESSIONID cookie 来创建会话。当您发出请求时,您不会首先获得该会话 ID。
我使用 Fiddler 嗅探了一个登录该站点的会话,发现 POST 是发送到不同的 URL,但它设置了 JSESSIONID cookie。因此,您需要首先获取 URL,使用 cookiehandler 捕获该 cookie,然后 POST 到此 URL:
post_url = 'http://www.broadinstitute.org/cmap/j_security_check'
您根本不需要保存 HTTP GET 请求,您只需调用 opener.open(url),然后在代码中将响应行更改为:
response = opener.open(post_url, binary_data)
此外,有效负载缺少提交方法。以下是我建议的更改的全部内容:
import http.cookiejar
import urllib
get_url = 'http://www.broadinstitute.org/cmap/index.jsp'
post_url = 'http://www.broadinstitute.org/cmap/j_security_check'
values = urllib.parse.urlencode({'j_username': <MYCOOLUSERNAME>,
'j_password': <MYCOOLPASSSWORD>,
'submit': 'sign in'})
payload = bytes(values, 'ascii')
cj = http.cookiejar.CookieJar()
opener = urllib.request.build_opener(
urllib.request.HTTPRedirectHandler(),
urllib.request.HTTPHandler(debuglevel=0),
urllib.request.HTTPSHandler(debuglevel=0),
urllib.request.HTTPCookieProcessor(cj))
opener.open(get_url) #First call to capture the JSESSIONID
resp = opener.open(post_url, payload)
resp_html = resp.read()
resp_headers = resp.info()
使用您创建的 opener 的任何其他请求都将重复使用该 cookie,并且您应该能够自由浏览该网站。