确定Python2和Python3之间http请求的差异

确定Python2和Python3之间http请求的差异,http,python-3.x,http-headers,python-2.x,api-key,Http,Python 3.x,Http Headers,Python 2.x,Api Key,我正在尝试使用Python3将度量发送到。网站上给出的示例是Python2,我已经成功地将TCP和UDP示例移植到Python3(尽管我没有经验,并且已经提交了示例,以便文档可以更新),但是我无法让HTTP方法工作 Python2示例如下所示: import urllib2, base64 url = "https://hostedgraphite.com/api/v1/sink" api_key = "YOUR-API-KEY" request = urllib2.Request(url,

我正在尝试使用Python3将度量发送到。网站上给出的示例是Python2,我已经成功地将TCP和UDP示例移植到Python3(尽管我没有经验,并且已经提交了示例,以便文档可以更新),但是我无法让HTTP方法工作

Python2示例如下所示:

import urllib2, base64

url = "https://hostedgraphite.com/api/v1/sink"
api_key = "YOUR-API-KEY"

request = urllib2.Request(url, "foo 1.2")
request.add_header("Authorization", "Basic %s" % base64.encodestring(api_key).strip())
result = urllib2.urlopen(request)
这将成功运行,返回HTTP 200

到目前为止,我已经将这些内容移植到Python3,虽然我(最终)能够让它发出有效的HTTP请求(即没有语法错误),但请求失败,返回HTTP 400

import urllib.request, base64

url = "https://hostedgraphite.com/api/v1/sink"
api_key = b'YOUR-API-KEY'

metric = "testing.python3.http 1".encode('utf-8')
request = urllib.request.Request(url, metric)
request.add_header("Authorization", "Basic %s" % base64.encodestring(api_key).strip())
result = urllib.request.urlopen(request)
全部结果是:

>>> result = urllib.request.urlopen(request)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/Cellar/python3/3.3.1/Frameworks/Python.framework/Versions/3.3/lib/python3.3/urllib/request.py", line 160, in urlopen
    return opener.open(url, data, timeout)
  File "/usr/local/Cellar/python3/3.3.1/Frameworks/Python.framework/Versions/3.3/lib/python3.3/urllib/request.py", line 479, in open
    response = meth(req, response)
  File "/usr/local/Cellar/python3/3.3.1/Frameworks/Python.framework/Versions/3.3/lib/python3.3/urllib/request.py", line 591, in http_response
    'http', request, response, code, msg, hdrs)
  File "/usr/local/Cellar/python3/3.3.1/Frameworks/Python.framework/Versions/3.3/lib/python3.3/urllib/request.py", line 517, in error
    return self._call_chain(*args)
  File "/usr/local/Cellar/python3/3.3.1/Frameworks/Python.framework/Versions/3.3/lib/python3.3/urllib/request.py", line 451, in _call_chain
    result = func(*args)
  File "/usr/local/Cellar/python3/3.3.1/Frameworks/Python.framework/Versions/3.3/lib/python3.3/urllib/request.py", line 599, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 400: Bad Request
>result=urllib.request.urlopen(请求)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“/usr/local/ceral/python3/3.3.1/Frameworks/Python.framework/Versions/3.3/lib/python3.3/urllib/request.py”,urlopen中第160行
返回opener.open(url、数据、超时)
文件“/usr/local/ceral/python3/3.3.1/Frameworks/Python.framework/Versions/3.3/lib/python3.3/urllib/request.py”,第479行,打开
响应=方法(请求,响应)
文件“/usr/local/ceral/python3/3.3.1/Frameworks/Python.framework/Versions/3.3/lib/python3.3/urllib/request.py”,第591行,在http_响应中
“http”、请求、响应、代码、消息、hdrs)
文件“/usr/local/ceral/python3/3.3.1/Frameworks/Python.framework/Versions/3.3/lib/python3.3/urllib/request.py”,第517行出错
返回自我。调用链(*args)
文件“/usr/local/ceral/python3/3.3.1/Frameworks/Python.framework/Versions/3.3/lib/python3.3/urllib/request.py”,第451行,在调用链中
结果=func(*args)
文件“/usr/local/ceral/python3/3.3.1/Frameworks/Python.framework/Versions/3.3/lib/python3.3/urllib/request.py”,第599行,默认为http\u error\u
raise HTTPError(请求完整的url、代码、消息、hdrs、fp)
urllib.error.HTTPError:HTTP错误400:请求错误

很明显我做错了什么吗?对于如何捕获和比较成功(python2)和失败(python3)请求实际发送的内容,有什么建议吗?

不要混合使用Unicode字符串和字节:

>>> "abc %s" % b"def"
"abc b'def'"
您可以按如下方式构造标头:

from base64 import b64encode

headers = {'Authorization': b'Basic ' + b64encode(api_key)}
查看请求的快速方法是将url中的主机更改为
localhost:8888
,并在发出请求之前运行:

$ nc -l 8888

您还可以使用wireshark查看请求。

数据包嗅探器说…?更新为
tcpdump
的结果,不幸的是数据包内容本身丢失。