问题 Pyinstaller错误ImportError:没有名为'requests.packages.chardet.sys的模块


我似乎无法找到这个的根本原因。我不知道它是pyinstaller,pip问题,请求模块还是别的东西,因为没有什么可以最终消除。

我在python中编写了一个脚本,当我们必须部署一个新单元时,它为我们的企业网络正确配置了一个新的硬件sonicwall。它在内存中配置正确的.exp文件,使用默认凭据登录到sonicwall设备,通过多部分数据表单导入文件,重新启动sonicwall,然后再次登录并正确更改共享密钥。出于安全原因,我不能在这里发布代码,但我可以用一个更简单的例子来解释这个问题。以前,代码使用urllib和urllib2来处理http请求,但是当我不得不重新编写脚本以包含csrfTokens时,我发现了请求模块。

长话短说,这个脚本在python解释器调用时效果很好。但是,当尝试使用pyinstaller编译它时,我得到了一系列错误,因为我已切换到请求而不是urllib。

更多背景:

Windows 7 - Python2.7.9
pip 6.0.8 from C:\Python27\lib\site-packages\pip-6.0.8-py2.7.egg (python 2.7)
pip freeze output:
pyinstaller==2.1.1.dev0
pywin32==219
requests==2.5.3

作为一个例子,我会给你一些炸弹的代码,一个简单的谷歌请求。

#!/usr/bin/python
import requests 
r = requests.get('https://google.com') 
print(r.text)

当我从python调用文件时,上面的代码适用于一个简单的请求,但是当我编译它时,我得到这个:

(编辑粘贴输出有问题,这里是pastebin) 引擎收录

它创建一个Windows可执行文件,但是当我尝试运行它时出现以下错误:

注意  我确实安装了ms c ++ 2008 redistributable以帮助清理msvcr90.dll,但我仍然得到上面的requests.packages.chardet.sys错误。

我已经尝试了我能想到的一切,安装chardet,安装chardet2,安装cchardet,强制pyinstaller的早期版本和递增请求。废弃pip并手动安装pyinstaler和请求。我的智慧结束了尝试的事情,我不太明白这里的错误。 requests.packages.chardet存在于系统中。我在Windows PATH中也有C:\ Python27,因为我可以从任何目录调用python。

如果您需要更多信息,请告诉我。我试图尽可能彻底地解决错误和我已安装的错误,但如果需要我可以提供更多错误。

  当我在导入请求时尝试编译时,这个问题似乎只会发生。创建测试脚本,beautifulsoup,urllib / 2等都编译一个正常运行的有效Windows exe。


11848
2018-02-27 22:17


起源

似乎与...有关 mail-archive.com/pyinstaller@googlegroups.com/msg00374.html 和 comments.gmane.org/gmane.comp.python.pyinstaller/3281 - Ian Stapleton Cordasco


答案:


我还没有解决方案,但这是由最新的变化引起的 requests 模块(版本2.5.2和2.5.3)。

现在你可以使用版本2.5.1,直到PyInstaller有合适的钩子来解决这个问题。

我无法解释这个问题,但看起来之间存在某种冲突 PyInstaller 导入钩子和一些最新的补充 requests (VendorAlias)。


9
2018-03-01 13:05



... 谢谢!你刚才回答了这个问题,今天我收到了错误。真棒! - swdev
m1keil,你刚刚保存了我头上留下的头发!我一直在解决这个问题并迫使请求2.5.1解决了!在我发布之前,我还发布了请求github问题跟踪器,所以他知道它。我也将这个帖子与他的问题跟踪器联系起来。但正如我所理解的那样,我们认为不一定所有的请求都是错误的,或者pyinstaller,似乎两者都是以不同的方式做事并且与导入挂钩和请求的新增内容发生碰撞? - Richard Cascarina
是的,这正是我的想法。 PyInstaller,py2exe等问题是底层Python模块需要“意识到”有时它运行在“冻结”状态。看起来确实如此。 - m1keil
只是徘徊,是这样的,并且解决方案将与导入zope.interface上的扭曲导入错误相同? *我不确定,我认为它在PyInstaller中称为伪导入 - swdev
@swdev,我个人不知道。我没有时间得到关于错误的太多细节,我对zope不熟悉。 - m1keil


好消息,这已在最新版本中修复 requests

pip install requests --upgrade

简单。


4
2017-10-21 00:59





正如m1keil所说,问题出在PyInstaller导入钩子和新的load_module请求功能之间,在 requests.packages.__init__.py 源文件。

调试此文件可以看到请求包的任何导入都通过load_module函数传递。这包括python标准包。这就是错误的原因。

我的解决方法包括编辑 requests.packages.__init__.py (在virtualenv文件夹中)版本2.5.3并在load_module函数的最开头添加这段代码:

    print "Requested name = ", name #Comment this line when it works
    direct_loaded_packages = ('sys', 'errno','logging','warnings'
            ,'socket','os','re','time','hashlib','base64'
            ,'time','collections','datetime','io', 'argparse'
            ,'codecs', 'Queue', 'zlib', 'ssl', 'operator'
            ,'types','platform','struct', 'StringIO','httplib'
            ,'simplejson','cookielib','urllib','urlparse'
            ,'urllib2','Cookie','http','binascii','certifi'
            ,'uuid','json','threading','dummy_thread','email'
            ,'email.utils','operator','mimetypes')    


    new_name = ''
    #Package with three directory deep 
    if '.'.join(name.split('.')[3:]) in direct_loaded_packages:
        new_name = '.'.join(name.split('.')[3:])
    #Package with four directory deep
    elif '.'.join(name.split('.')[4:]) in direct_loaded_packages:
        new_name = '.'.join(name.split('.')[4:])
    #Package with five directory deep
    elif '.'.join(name.split('.')[5:]) in direct_loaded_packages:
        new_name = '.'.join(name.split('.')[5:])

    if new_name != '':
        module = __import__(new_name)
        return module 

通过测试和错误以及grepping我已经构建了必须直接加载而不通过load_module函数的包列表。

不优雅,但它的工作原理。我测试了一个更优雅的解决方案,但我还没有成功。


1
2018-03-18 16:12





我认为问题是出于问题 setuptools的 版本,所以尝试使用旧版本并再次测试它。就我而言,它有效!

>> pip uninstall setuptools
>> pip install setuptools==12.0.5

我猜这个麻烦与位置论证的解释有关


-1
2018-03-14 20:00



我尝试过这个并不适合我。 - Jonathan