独立 Python 可执行文件(使用 PyInstaller 编译)无法通过代理,但是当执行未编译的源代码时一切正常

Standalone Python executable (compiled with PyInstaller) cannot pass through proxy, but when uncompiled source is executed everything works properly

我在我的 Windows 10 机器上使用 PyInstaller 编译了一些 python 源代码,目的是将此 .exe 传递给不一定有 Python 的最终用户安装在他们的电脑上。源代码使用请求库 (1) 通过公司代理,(2) 在 openDAP 服务器上进行身份验证,以及 (3) 下载指定文件。

当我 运行 我的源代码在 IPython 中时,一切正常。当我从命令行 运行 源代码时,再次一切正常。但是当我使用 PyInstaller 编译并尝试 运行 来自生成的可执行文件的代码时,我收到以下错误:

Traceback (most recent call last):                                                                                   
File "urllib3\connectionpool.py", line 696, in urlopen                                                             
File "urllib3\connectionpool.py", line 964, in _prepare_proxy                                                      
File "urllib3\connection.py", line 358, in connect                                                                 
File "urllib3\connection.py", line 187, in _new_conn                                                             
urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPSConnection object at 
0x000001E14DE48588>: Failed to establish a new connection: [Errno 11003] getaddrinfo failed 

Traceback (most recent call last):                                                                                   
File "requests\adapters.py", line 449, in send                                                                     
File "urllib3\connectionpool.py", line 756, in urlopen                                                             
File "urllib3\util\retry.py", line 574, in increment                                                             
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='<the correct host address was here>', 
port=443): Max retries exceeded with url: 
<the correct opendap url was here> (Caused by ProxyError('Cannot connect to proxy.', 
NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x000001E14DE48588>: Failed 
to establish a new connection: [Errno 11003] getaddrinfo failed'))) 

Traceback (most recent call last):                                                                                   
File "my_script_calls were here", line 29, in <module>                                                                                                                                            
File "requests\api.py", line 75, in get                                                                            
File "requests\api.py", line 61, in request                                                                        
File "requests\sessions.py", line 542, in request                                                                  
File "requests\sessions.py", line 655, in send                                                                     
File "requests\adapters.py", line 510, in send                                                                   
requests.exceptions.ProxyError: HTTPSConnectionPool(host='<the correct host was here>', 
port=443): Max retries exceeded with url: 
<the correct opendap url was here> (Caused by ProxyError('Cannot connect to proxy.', 
NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x000001E14DE48588>: Failed 
to establish a new connection: [Errno 11003] getaddrinfo failed')))                                         
[23352] Failed to execute script my_script_was_here                                

任何故障排除帮助将不胜感激。到目前为止,我有: (1) 验证 PyInstaller 在正确的 python 环境和正确的 python 解释器中 运行ning (2) 验证这不是解析配置文件以获取代理信息的问题(所有解析的文件都已正确导入) (3) 不是由于密码中的特殊字符(我已经尝试过 ascii 和 URL-encoded) (4) 确认测试用例使用未编译的源代码。

我注意到 my_script/build/warn-my_script.txt 中充满了缺失的模块。试图将路径传递给 pyinstaller al a:

  PyInstaller --paths=path/to/my/env/Lib/site-packages --paths=path/to/my/env/Library/bin --onedir my_script.py

唉,安装程序仍然找不到这些模块:

     missing module named org - imported by copy (optional)
missing module named _posixsubprocess - imported by subprocess (conditional)
missing module named pwd - imported by posixpath (delayed, conditional), shutil (optional), tarfile (optional), http.server (delayed, optional), webbrowser (delayed), pathlib (delayed, conditional, optional), netrc (delayed, conditional), getpass (delayed)
missing module named posix - imported by os (conditional, optional)
missing module named resource - imported by posix (top-level)
missing module named grp - imported by shutil (optional), tarfile (optional), pathlib (delayed)
missing module named urllib.getproxies_environment - imported by urllib (conditional), requests.compat (conditional)
missing module named urllib.proxy_bypass_environment - imported by urllib (conditional), requests.compat (conditional)
missing module named urllib.proxy_bypass - imported by urllib (conditional), requests.compat (conditional)
missing module named urllib.getproxies - imported by urllib (conditional), requests.compat (conditional)
missing module named urllib.urlencode - imported by urllib (conditional), requests.compat (conditional)
missing module named urllib.unquote_plus - imported by urllib (conditional), requests.compat (conditional)
missing module named urllib.quote_plus - imported by urllib (conditional), requests.compat (conditional)
missing module named urllib.unquote - imported by urllib (conditional), requests.compat (conditional)
missing module named urllib.quote - imported by urllib (conditional), requests.compat (conditional)
missing module named termios - imported by tty (top-level), getpass (optional)
missing module named vms_lib - imported by platform (delayed, conditional, optional)
missing module named 'java.lang' - imported by platform (delayed, optional), xml.sax._exceptions (conditional)
missing module named java - imported by platform (delayed)
missing module named _scproxy - imported by urllib.request (conditional)
missing module named _winreg - imported by platform (delayed, optional), requests.utils (delayed, conditional, optional)
missing module named _frozen_importlib_external - imported by importlib._bootstrap (delayed), importlib (optional), importlib.abc (optional)
excluded module named _frozen_importlib - imported by importlib (optional), importlib.abc (optional)
missing module named console - imported by pyreadline.console.ansi (conditional)
missing module named startup - imported by pyreadline.keysyms.common (conditional), pyreadline.keysyms.keysyms (conditional)
missing module named sets - imported by pyreadline.keysyms.common (optional)
missing module named System - imported by pyreadline.clipboard.ironpython_clipboard (top-level), pyreadline.keysyms.ironpython_keysyms (top-level), pyreadline.console.ironpython_console (top-level), pyreadline.rlmain (conditional)
missing module named StringIO - imported by pyreadline.py3k_compat (conditional), urllib3.packages.six (conditional), six (conditional), simplejson.compat (conditional, optional), requests.compat (conditional)
missing module named IronPythonConsole - imported by pyreadline.console.ironpython_console (top-level)
missing module named clr - imported by pyreadline.clipboard.ironpython_clipboard (top-level), pyreadline.console.ironpython_console (top-level)
missing module named 'org.python' - imported by pickle (optional), xml.sax (delayed, conditional)
missing module named Cookie - imported by requests.compat (conditional)
missing module named cookielib - imported by requests.compat (conditional)
missing module named urllib2 - imported by requests.compat (conditional)
missing module named urlparse - imported by requests.compat (conditional)
missing module named UserDict - imported by simplejson.ordered_dict (top-level)
missing module named cStringIO - imported by simplejson.compat (conditional, optional)
missing module named copy_reg - imported by cStringIO (top-level)
missing module named Queue - imported by urllib3.util.queue (conditional)
missing module named "'urllib3.packages.six.moves.urllib'.parse" - imported by urllib3.request (top-level), urllib3.poolmanager (top-level)
runtime module named urllib3.packages.six.moves - imported by http.client (top-level), urllib3.connectionpool (top-level), urllib3.util.response (top-level), 'urllib3.packages.six.moves.urllib' (top-level), urllib3.response (top-level), urllib3.util.queue (top-level)
missing module named 'backports.ssl_match_hostname' - imported by urllib3.packages.ssl_match_hostname (optional)
missing module named _abcoll - imported by urllib3.packages.ordered_dict (optional)
missing module named dummy_thread - imported by urllib3.packages.ordered_dict (optional)
missing module named thread - imported by urllib3.packages.ordered_dict (optional)
missing module named _dummy_threading - imported by dummy_threading (optional)
missing module named 'typing.io' - imported by importlib.resources (top-level)
missing module named bcrypt - imported by cryptography.hazmat.primitives.serialization.ssh (optional)
missing module named cryptography.x509.UnsupportedExtension - imported by cryptography.x509 (optional), urllib3.contrib.pyopenssl (optional)
missing module named unicodedata2 - imported by charset_normalizer.hook (optional)

我知道其中许多是兼容包要求的过时模块,所以这可能不是问题的根源?

此问题已解决。我还没有找出根本原因,但已确定这是由于 ntpath.py 的问题所致。我试图在已安装的网络共享上编译该程序。我注意到,在尝试构建一个简单的 conda 环境来诊断此问题时,由于 ntpath.py WinError 59,我无法安装请求模块。

  File "C:\Users\myuser\pyenv\lp38\lib\ntpath.py", line 601, in _getfinalpathname_nonstrict                               
  path = _getfinalpathname(path)                                                                                    
  OSError: [WinError 59] An unexpected network error occurred: 
 'H:\my_path\exec_prep\my_script'  

我将我的项目重新定位到我的本地驱动器,编译了 python 代码,瞧,它按预期工作。进一步测试表明可执行文件必须驻留在本地驱动器上,不能从 Microsoft Windows 网络共享驱动器上执行。

多么令人沮丧。