python3 urllib.request.urlopen函数在ubuntu 16.04上失败,但可在其他9个操作系统上运行

时间:2019-06-01 21:12:45

标签: python ssl ubuntu-16.04 urllib

我有一个小的python3函数,可以使用urllib.request.urlopenurllib.request.urlretrieve从Internet下载一些文件。我在基于ubuntu 16.04的docker容器中的更大代码中运行此功能。尝试使用http协议下载文件时,调用失败,错误代码为503 Service Unavailable。从https服务器下载网页内容时,握手期间呼叫失败。

以下是我从http服务器下载一些tarball的电话:

url = "http://example.com/file.tar.gz"
urllib.request.urlretrieve(url, "file.tar.gz")

以上通话失败,并显示错误

File "/usr/lib/python3.5/urllib/request.py", line 188, in urlretrieve
File "/usr/lib/python3.5/urllib/request.py", line 163, in urlopen
    return opener.open(url, data, timeout)
File "/usr/lib/python3.5/urllib/request.py", line 472, in open
    response = meth(req, response)
File "/usr/lib/python3.5/urllib/request.py", line 582, in http_response
    'http', request, response, code, msg, hdrs)
File "/usr/lib/python3.5/urllib/request.py", line 510, in error
    return self._call_chain(*args)
File "/usr/lib/python3.5/urllib/request.py", line 444, in _call_chain
    result = func(*args)
File "/usr/lib/python3.5/urllib/request.py", line 590, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 503: Service Unavailable

以下是我对https的处理方式:

def download_report(self, id, output_file):
    ssl_def_function = ssl._create_default_https_context
    ssl._create_default_https_context = ssl._create_unverified_context
    css = urllib.request.urlopen(self.url + "/print.css")
    report = urllib.request.urlopen(self.url + "/run/" + id + "/report/")
    with open(output_file, "w+") as f:
        # We need to embed the CSS first
        css = str(css.read(), "utf-8")
        report = str(report.read(), "utf-8").replace("<head>", "<head><style>%s</style>" % css)
        f.write(report)
    ssl._create_default_https_context = ssl_def_function

,但以下操作失败:

Traceback (most recent call last):
  File "/usr/lib/python3.5/urllib/request.py", line 1254, in do_open
    h.request(req.get_method(), req.selector, req.data, headers)
  File "/usr/lib/python3.5/http/client.py", line 1106, in request
    self._send_request(method, url, body, headers)
  File "/usr/lib/python3.5/http/client.py", line 1151, in _send_request
    self.endheaders(body)
  File "/usr/lib/python3.5/http/client.py", line 1102, in endheaders
    self._send_output(message_body)
  File "/usr/lib/python3.5/http/client.py", line 934, in _send_output
    self.send(msg)
  File "/usr/lib/python3.5/http/client.py", line 877, in send
    self.connect()
  File "/usr/lib/python3.5/http/client.py", line 1260, in connect
    server_hostname=server_hostname)
  File "/usr/lib/python3.5/ssl.py", line 377, in wrap_socket
    _context=self)
  File "/usr/lib/python3.5/ssl.py", line 752, in __init__
    self.do_handshake()
  File "/usr/lib/python3.5/ssl.py", line 988, in do_handshake
    self._sslobj.do_handshake()
  File "/usr/lib/python3.5/ssl.py", line 633, in do_handshake
    self._sslobj.do_handshake()
ConnectionResetError: [Errno 104] Connection reset by peer

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/mm/Downloads/pycharm-community-2019.1.3/helpers/pydev/pydevd.py", line 1758, in <module>
    main()
  File "/home/mm/Downloads/pycharm-community-2019.1.3/helpers/pydev/pydevd.py", line 1752, in main
    globals = debugger.run(setup['file'], None, None, is_module)
  File "/home/mm/Downloads/pycharm-community-2019.1.3/helpers/pydev/pydevd.py", line 1147, in run
    pydev_imports.execfile(file, globals, locals)  # execute the script
  File "/home/mm/Downloads/pycharm-community-2019.1.3/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "/tmp/prj/Uploader.py", line 148, in <module>
    handler.download_report(id), output_file)
  File "/tmp/prj/Helper.py", line 251, in download_report
    css = urllib.request.urlopen(self.url + "/print.css")
  File "/usr/lib/python3.5/urllib/request.py", line 163, in urlopen
    return opener.open(url, data, timeout)
  File "/usr/lib/python3.5/urllib/request.py", line 466, in open
    response = self._open(req, data)
  File "/usr/lib/python3.5/urllib/request.py", line 484, in _open
    '_open', req)
  File "/usr/lib/python3.5/urllib/request.py", line 444, in _call_chain
    result = func(*args)
  File "/usr/lib/python3.5/urllib/request.py", line 1297, in https_open
    context=self._context, check_hostname=self._check_hostname)
  File "/usr/lib/python3.5/urllib/request.py", line 1256, in do_open
    raise URLError(err)
urllib.error.URLError: <urlopen error [Errno 104] Connection reset by peer>

Process finished with exit code 1

值得一提的是,相同的代码可在以下操作系统(docker容器)上完美运行,但仅在Ubuntu 16.04上失败

  • Ubuntu(14.04,18.04)
  • Fedora(27、28、29)
  • CentOS(7.4,7.5)
  • OpenSuse(42.3,15.0)
  • Windows 我什至在VM上安装了ubuntu 16.04,它也失败了。我还尝试在多台计算机上运行容器,但它们均因相同的错误而失败。这让我思考了两天,但找不到解决方案。我确保已安装openssl和libssl-dev。我也尝试通过编译python 3.7。 谢谢您的帮助。

0 个答案:

没有答案