web-dev-qa-db-ja.com

PyinstallerエラーImportError: 'requests.packages.chardet.sysという名前のモジュールがありません

これの根本的な原因を見つけることができないようです。それがpyinstallerなのか、pipの問題なのか、requestsモジュールなのか、それとも他の何かなのかはわかりません。決定的に排除できるものはないからです。

pythonで、新しいユニットをデプロイする必要があるときに、エンタープライズネットワーク用の新しいハードウェアsonicwallを適切に構成するスクリプトを作成しました。メモリ内に適切な.expファイルを構成し、sonicwallデバイスにログインします。デフォルトの資格情報を使用して、マルチパートデータフォームを介してファイルをインポートし、sonicwallを再起動してから、再度ログインし、共有シークレットを適切に変更します。セキュリティ上の理由から、ここにコードを投稿することはできませんが、問題を説明することはできます。以前は、コードはurllibとurllib2を使用してhttpリクエストを処理していましたが、スクリプトを書き直してcsrfTokensを含める必要があるときに、リクエストモジュールを発見しました。

簡単に言うと、スクリプトはpythonインタープリターによって呼び出されたときに驚くほど機能します。しかし、pyinstallerでコンパイルしようとすると、代わりにリクエストに切り替えたため、一連のエラーが発生します。 urllibs。

もう少し背景:

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からファイルを呼び出すと単純なリクエストで機能しますが、コンパイルすると次のようになります。

(編集出力の貼り付けに問題があります。これがペーストビンです) ペーストビン

Windows実行可能ファイルが作成されますが、実行しようとすると次のエラーが発生します。

[〜#〜] note [〜#〜]msvcr90.dllをクリアするために再配布可能なms c ++ 2008をインストールしましたが、それでも取得します上記のrequests.packages.chardet.sysエラー。

私は、chardetのインストール、ch​​ardet2のインストール、cchardetのインストール、以前のバージョンのpyinstallerと要求を段階的に強制するなど、考えられるすべてのことを試しました。ピップを廃棄し、pyinstalerとリクエストを手動でインストールします。私は試してみることができるようになりました。ここでエラーが発生することはあまりありません。 requests.packages.chardetがシステムに存在します。また、任意のディレクトリからpythonを呼び出すことができるため、Windows PATHにC:\ Python27があります。

さらに詳しい情報が必要な場合は、お知らせください。私は可能な限りエラーとインストールしたものを徹底的に調べようとしましたが、必要に応じてさらに提供することができます。

[〜#〜] also [〜#〜]この問題は、リクエストをインポートするときにコンパイルしようとしたときにのみ発生するようです。テストスクリプト、beautifulsoup、urllib/2などの作成はすべて、正しく実行される有効なWindowsexeをコンパイルします。

12

これに対する解決策はまだありませんが、これはrequestsモジュール(バージョン2.5.2および2.5.3)の最新の変更が原因です。

今のところ、PyInstallerがこの問題を解決するための適切なフックを持つまで、バージョン2.5.1を使用できます。

この問題を実際に説明することはできませんが、PyInstallerインポートフックとrequestsへの最新の追加( VendorAlias )の間に何らかの衝突があるようです。

9
m1keil

朗報です。これは最新バージョンのrequestsで修正されています。

pip install requests --upgrade

簡単。

4
Jonathan

M1keilが言うように、問題はPyInstallerインポートフックと、requests.packages.__init__.pyソースファイルに実装されているリクエストの新しいload_module機能の間にあります。

このファイルをデバッグすると、requestsパッケージのインポートがload_module関数を通過していることがわかります。これにはpython標準パッケージが含まれます。これがエラーの理由です。

私の回避策は、バージョン2.5.3のrequests.packages.__init__.py(virtualenvフォルダー内)を編集し、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 

Test&errorとgreppingによって、load_module関数を渡さずに直接ロードする必要があるパッケージのリストを作成しました。

エレガントではありませんが、機能します。より洗練されたソリューションをテストしましたが、成功しませんでした。

1
Tomàs Reverter

python実行可能ファイル(例:「requestsという名前のモジュールなし」、「cv2という名前のモジュールなし」など)を実行すると、サーバーエラーが発生しました。setuptoolsをアップグレードして解決しました。

pip install setuptools --upgrade
0
Ben Van Daele