带有 Python 请求模块的 HTTP 摘要/基本身份验证

use*_*107 8 xml http digest-authentication python-3.x python-requests

我的目标是能够html/xml data从受密码保护的页面进行解析,然后根据我需要发送xml commands到另一台设备的数据(时间戳)进行解析。我试图访问的页面是由 IP 设备生成的网络服务器。另外,如果用另一种语言更容易完成,请告诉我。我的编程经验很少(一门C编程课)

我曾尝试使用 Requests for Basic 和 Digest Auth。我仍然无法通过身份验证,这使我无法进一步了解。

这是我的尝试:

import requests
from requests.auth import HTTPDigestAuth

url='http://myUsername:myPassword@example.com/cgi/metadata.cgi?template=html'
r = requests.get(url, auth=HTTPDigestAuth('myUsername', 'myPassword'))        
r.status_code

print(r.headers) 
print(r.status_code)
Run Code Online (Sandbox Code Playgroud)

输出:

401 
CaseInsensitiveDict({'Content-Length': '0', 'WWW-Authenticate': 'Digest realm="the realm of device", nonce="23cde09025c589f05f153b81306928c8", qop="auth"', 'Server': 'Device server name'})
Run Code Online (Sandbox Code Playgroud)

我也尝试BasicAuth过请求并获得相同的输出。我已经尝试过包括user:pass@url 内的 和 不包括在内。尽管当我将该输入放入浏览器时,它可以工作。

我认为请求处理了标头数据,Digest/BasicAuth但也许我还需要包含标头?

我使用了 Live HTTP Headers(firefox) 并得到了这个:

GET /cgi/metadata.cgi?template=html
HTTP/1.1 
Host: [Device IP] 
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8 Accept-Language: en-US,en;q=0.5 
Accept-Encoding: gzip, deflate DNT: 1 Connection: keep-alive
HTTP/1.1 401 Unauthorized WWW-Authenticate: Digest realm="Device Realm", nonce="a2333eec4cce86f78016343c48382d21", 
qop="auth" 
Server: Device Server Content-Length: 0
Run Code Online (Sandbox Code Playgroud)

jfs*_*jfs 7

这两个请求是独立的:

r = requests.get(url, auth=HTTPDigestAuth('user', 'pass')) 
response = requests.get(url) #XXX <-- DROP IT
Run Code Online (Sandbox Code Playgroud)

第二个请求不发送任何凭据。因此它收到401 Unauthorizedhttp 响应状态也就不足为奇了。

要解决这个问题:

  1. 使用与url您在浏览器中使用的相同。最后落下digest-auth/auth/user/pass。这只是请求文档中的一个示例
  2. 打印r.status_code而不是response.status_code查看是否成功。

为什么要在 url 和auth参数中使用用户名/密码?从 url 中删除用户名/密码。要查看发送的请求和响应标头,您可以启用日志记录/调试

import logging
import requests
from requests.auth import HTTPDigestAuth

# these two lines enable debugging at httplib level (requests->urllib3->httplib)
# you will see the REQUEST, including HEADERS and DATA, 
# and RESPONSE with HEADERS but without DATA.
# the only thing missing will be the response.body which is not logged.
try:
    import httplib
except ImportError:
    import http.client as httplib

httplib.HTTPConnection.debuglevel = 1

logging.basicConfig(level=logging.DEBUG) # you need to initialize logging, 
                      # otherwise you will not see anything from requests

# make request
url = 'https://example.com/cgi/metadata.cgi?template=html'
r = requests.get(url, auth=HTTPDigestAuth('myUsername', 'myPassword'),
                 timeout=10)
print(r.status_code)
print(r.headers)
Run Code Online (Sandbox Code Playgroud)