使用请求时无法在页面之间保留登录凭据

时间:2015-05-20 21:17:35

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

我很擅长在python中使用urllibrequests模块。我正在尝试访问我公司网站上的wikipage,当我尝试通过浏览器访问时,我需要通过弹出窗口提供我的登录凭据。

我能够编写以下脚本来成功访问网页并使用以下代码阅读:

import sys
import urllib.parse
import urllib.request
import getpass
import http.cookiejar

wiki_page = 'http://wiki.company.com/wiki_page'
top_level_url = 'http://login.company.com/'

username = input("Enter Username: ")
password = getpass.getpass('Enter Password: ')

# Authenticate with login server and fetch the wiki page
password_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
cj = http.cookiejar.CookieJar()
password_mgr.add_password(None, top_level_url, username, password)
handler = urllib.request.HTTPBasicAuthHandler(password_mgr)
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj),handler)
opener.open(wiki_page)
urllib.request.install_opener(opener)

with urllib.request.urlopen(wiki_page) as response:
    # Do something

但是现在我需要使用requests模块来做同样的事情。我尝试使用几种方法,包括会话但无法使其工作。以下是我认为接近实际解决方案的一段代码,但它在第一次打印中给出了Response 200,在第二次打印时给出了Response 401:

s = requests.Session()
print(s.post('http://login.company.com/', auth=(username, password)))  # I have tried s.post() as well as s.get() in this line
print(s.get('http://wiki.company.com/wiki_page'))

1 个答案:

答案 0 :(得分:1)

该网站使用基本身份验证授权方案;您需要在每次请求时发送登录凭据。

使用会话中的用户名和密码将Session.auth attribute设置为元组:

s = requests.Session()
s.auth = (username, password)

response = s.get('http://wiki.company.com/wiki_page')
print(response.text)

urllib.request.HTTPPasswordMgrWithDefaultRealm()对象通常只会响应以<{1}} 启动的网址上的挑战(因此任何更深的路径也会这样做),而不是将密码发送到其他位置。

如果简单方法(设置http://login.company.com/)不起作用,您需要通过直接访问Session.auth找出返回的响应,这就是您的原始代码确实。如果服务器重定向您到登录页面,然后使用基本身份验证信息,您可以复制它:

http://wiki.company.com/wiki_page

您必须仔细调查从服务器获得的响应。打开一个交互式控制台,看看你得到的回复。请查看s = requests.Session() response = s.get('http://wiki.company.com/wiki_page', allow_redirects=False) if response.status_code in (302, 303): target = response.headers['location'] authenticated = s.get(target, auth=(username, password)) # continue on to the wiki again response = s.get('http://wiki.company.com/wiki_page') response.status_code以及response.headers以获取提示。如果您将response.text保留为默认allow_redirects,请查看True以查看是否存在任何中间重定向。