机械化Python和授权,而不会先得到401错误

时间:2011-12-08 03:20:12

标签: python http authentication mechanize

我正在尝试使用Mechanize来自动化与非常挑剔的遗留系统的交互。特别是,在第一个登录页面之后,必须在每次请求时将授权发送出系统。不幸的是,Mechanize似乎满足于仅在首次获得401 Unauthorized错误后发送授权。有没有办法让它每次发送授权?

以下是一些示例代码:

br.add_password("http://example.com/securepage", "USERNAME", "PASSWORD", "/MYREALM")
br.follow_link(link_to_secure_page) # where the url is the previous URL

以下是我从调试Mechanize获得的响应:

send: 'GET /securepage HTTP/1.1\r\nAccept-Encoding: identity\r\nHost: example.com\r\nReferer: http://example.com/home\r\nConnection: close\r\nUser-Agent: Python-urllib/2.7\r\n\r\n'
reply: 'HTTP/1.1 401 Unauthorized\r\n'
header: Server: Tandy1000Web
header: Date: Thu, 08 Dec 2011 03:08:04 GMT
header: Connection: close
header: Expires: Tue, 01 Jan 1980 06:00:00 GMT
header: Content-Type: text/html; charset=US-ASCII
header: Content-Length: 210
header: WWW-Authenticate: Basic realm="/MYREALM"
header: Cache-control: no-cache
send: 'GET /securepage HTTP/1.1\r\nAccept-Encoding: identity\r\nHost: example.com\r\nReferer: http://example.com/home\r\nConnection: close\r\nAuthorization: Basic VVNFUk5BTUU6UEFTU1dPUkQ=\r\nUser-Agent: Python-urllib/2.7\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
header: Server: Tandy1000Web
header: Date: Thu, 08 Dec 2011 03:08:07 GMT
header: Connection: close
header: Last-Modified: Thu, 08 Dec 2011 03:08:06 GMT
header: Expires: Tue, 01 Jan 1980 06:00:00 GMT
header: Content-Type: text/html; charset=UTF-8
header: Content-Length: 33333
header: Cache-control: no-cache

问题是,与GET请求的现代Web应用程序中应该发生的情况相反,通过首先点击401错误,我得到了错误的页面。我已经用CURL和urllib2确认,如果我通过在第一个请求中传入auth标头直接点击URL,我会得到正确的页面。

有关如何告诉机械化始终发送auth标头并避免第一个401错误的任何提示?这需要在客户端修复。我无法修改服务器。

1 个答案:

答案 0 :(得分:2)

from base64 import b64encode
import mechanize

url = 'http://192.168.3.5/table.js'
username = 'admin'
password = 'password'

# I have had to add a carriage return ('%s:%s\n'), but
# you may not have to.
b64login = b64encode('%s:%s' % (username, password))

br = mechanize.Browser()

# # I needed to change to Mozilla for mine, but most do not
# br.addheaders= [('User-agent', 'Mozilla/5.0')]

br.addheaders.append( 
  ('Authorization', 'Basic %s' % b64login )
)

br.open(url)
r = br.response()
data = r.read()

print data