将HTTP-POST-Request从PHP转换为Python3

时间:2017-12-20 15:01:32

标签: php python-3.x http-post urllib php-curl

我想在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>

欢迎任何帮助。

0 个答案:

没有答案