我想在Python3中发出POST请求。我必须传递一些自定义标头,数据必须是JSON编码的。 Web服务器使用自签名证书。我在PHP中得到了一个可以作为指导的工作示例。以下是该示例的片段。
$options = self::setHeaders($attributes);
$defaults = array(
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HEADER => 0,
CURLOPT_URL => $url,
CURLOPT_FRESH_CONNECT => 1,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_FORBID_REUSE => 1,
CURLOPT_TIMEOUT => 4,
CURLOPT_SSL_VERIFYPEER => 0,
CURLOPT_SSL_VERIFYHOST => 0,
CURLOPT_SSLVERSION => 3,
CURLOPT_POSTFIELDS => $attributes
);
$ch = curl_init();
curl_setopt_array($ch, ($options + $defaults));
if (!$result = curl_exec($ch)) {
trigger_error(curl_error($ch));
}
curl_close($ch);
我在Python3中的天真方法如下:
import urllib.request
import json
import ssl
url = "https://someRandomService.com/someRandomEndpoint"
headers = {
"User-Agent": "Mozilla/5.0",
# some more custom headers ...
}
data = {
"arg1": "random_value",
# some more data ...
}
data = json.dumps(data).encode("UTF-8") # data should be bytes
request = urllib.request.Request(url, data=data, headers=headers)
context = ssl.create_default_context()
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
with urllib.request.urlopen(request, context=context) as response:
content = response.read()
print(content)
我的代码甚至无法建立与服务器的连接,我不知道为什么。我得到的只是这个ConnectionResetError:
Traceback (most recent call last):
File "C:\Users\Daniel\AppData\Local\Programs\Python\Python36\lib\urllib\request.py", line 1318, in do_open
encode_chunked=req.has_header('Transfer-encoding'))
File "C:\Users\Daniel\AppData\Local\Programs\Python\Python36\lib\http\client.py", line 1239, in request
self._send_request(method, url, body, headers, encode_chunked)
File "C:\Users\Daniel\AppData\Local\Programs\Python\Python36\lib\http\client.py", line 1285, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
File "C:\Users\Daniel\AppData\Local\Programs\Python\Python36\lib\http\client.py", line 1234, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File "C:\Users\Daniel\AppData\Local\Programs\Python\Python36\lib\http\client.py", line 1026, in _send_output
self.send(msg)
File "C:\Users\Daniel\AppData\Local\Programs\Python\Python36\lib\http\client.py", line 964, in send
self.connect()
File "C:\Users\Daniel\AppData\Local\Programs\Python\Python36\lib\http\client.py", line 1400, in connect
server_hostname=server_hostname)
File "C:\Users\Daniel\AppData\Local\Programs\Python\Python36\lib\ssl.py", line 401, in wrap_socket
_context=self, _session=session)
File "C:\Users\Daniel\AppData\Local\Programs\Python\Python36\lib\ssl.py", line 808, in __init__
self.do_handshake()
File "C:\Users\Daniel\AppData\Local\Programs\Python\Python36\lib\ssl.py", line 1061, in do_handshake
self._sslobj.do_handshake()
File "C:\Users\Daniel\AppData\Local\Programs\Python\Python36\lib\ssl.py", line 683, in do_handshake
self._sslobj.do_handshake()
ConnectionResetError: [WinError 10054] Eine vorhandene Verbindung wurde vom Remotehost geschlossen
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File ".\test.py", line 34, in <module>
with urllib.request.urlopen(request, context=ctx) as response:
File "C:\Users\Daniel\AppData\Local\Programs\Python\Python36\lib\urllib\request.py", line 223, in urlopen
return opener.open(url, data, timeout)
File "C:\Users\Daniel\AppData\Local\Programs\Python\Python36\lib\urllib\request.py", line 526, in open
response = self._open(req, data)
File "C:\Users\Daniel\AppData\Local\Programs\Python\Python36\lib\urllib\request.py", line 544, in _open
'_open', req)
File "C:\Users\Daniel\AppData\Local\Programs\Python\Python36\lib\urllib\request.py", line 504, in _call_chain
result = func(*args)
File "C:\Users\Daniel\AppData\Local\Programs\Python\Python36\lib\urllib\request.py", line 1361, in https_open
context=self._context, check_hostname=self._check_hostname)
File "C:\Users\Daniel\AppData\Local\Programs\Python\Python36\lib\urllib\request.py", line 1320, in do_open
raise URLError(err)
urllib.error.URLError: <urlopen error [WinError 10054] Eine vorhandene Verbindung wurde vom Remotehost geschlossen>
欢迎任何帮助。