python3 beautifulsoup4 import問題

はじめに

 以前の記事に書いた通り、自分はdiscord botを制作している。osu!というPCゲーム用のbotである。
 最近になって、サーバ状態を表示する機能を実装したいと考えた。実装方法はコマンドを打つとサーバ状態のwebページのurlを表示する方法である。
 しかし、この方法ではブラウザをわざわざ立ち上げてwebページを見る必要があり、手間である。そこで、beautifulsoup4を使用し、webページから必要な情報だけを抽出してbotにdiscordメッセージとして送信させる方法を考えた。
 当方はpython初心者なのであーだこーだ調べながら作業していたが、beautifulsoup4がimportできない問題が発生した。この記事には解決方法を示す。もしかしたら、もしかすると、根本的な解決方法ではなかったりする。

beautifulsoup4のimport問題

 beautifulsoup4は以下の通りinstallした。

pip3 install beautifulsoup4


 以下のコードの部分で問題が起きた。

from bs4 import BeautifulSoup

 エラー文は以下の通り。

ImportError: No module named 'bs4'

 そこで、インストールされているモジュールを確かめた。確認結果は以下の通りであった。

>pip3 list

Package        Version
-------------- ---------
aiohttp        3.5.4
async-timeout  3.0.1
attrs          19.3.0
beautifulsoup4 4.8.2
certifi        2019.9.11
chardet        3.0.4
discord.py     1.2.5
googletrans    2.4.0
idna           2.8
multidict      4.6.1
pip            20.0.2
requests       2.22.0
setuptools     42.0.1
soupsieve      2.0
urllib3        1.25.7
websockets     6.0
yarl           1.3.0

>python3 -m pip list

Package       Version
------------- ---------
aiohttp       3.5.4
async-timeout 3.0.1
attrs         19.3.0
certifi       2019.9.11
chardet       3.0.4
discord.py    1.2.5
googletrans   2.4.0
idna          2.8
multidict     4.6.1
pip           20.0.2
requests      2.22.0
urllib3       1.25.7
websockets    6.0
yarl          1.3.0

 python3のlistにbeautifulsoup4が入っていなかった。インストール先のディレクトリを調査した結果、pip3のlistで表示されたモジュールとpython3のlistで表示されたモジュールのディレクトリ場所が異なっていた。

・pip3 C:\Users\Me\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.7_qbz5n2kfra8p0\LocalCache\local-packages\Python37\site-packages\

・python3
C:\Users\Me\AppData\Local\Programs\Python\Python37\Lib\site-packages

 なぜだ。。。という問題は置いておく。←オイオイ
 python3実行時にはC:\Users\Me\AppData\Local\Programs\Python\Python37\Lib\site-packages
のディレクトリ内のモジュールが使われているっぽい。つまり、pip3を使用した時、モジュールが全く参照もされないディレクトリにインストールされてしまう、らしい。自分の場合は。
 つまり、python3実行時に参照されるディレクトリにbeautifulsoup4が無いことがエラーが出る原因である。

解決方法

 いたってシンプル(怠惰)に解決する。pip3使用時にインストール対象のディレクトリ先を指定するオプションを使用して無理やりC:\Users\Me\AppData\Local\Programs\Python\Python37\Lib\site-packages
にインストールする。
使用コマンドは以下の通り。

pip install --user --install-option="--install-purelib=C:\Users\Me\AppData\Local\Programs\Python\Python37\Lib\site-packages" beautifulsoup4

 結果は以下の通り。

>pip install --user --install-option="--install-purelib=C:\Users\Me\AppData\Local\Programs\Python\Python37\Lib\site-packages" beautifulsoup4

C:\Users\Me\AppData\Local\Programs\Python\Python37\Lib\site-packages\pip\_internal\commands\install.py:244: UserWarning: Disabling all use of wheels due to the use of --build-option / --global-option / --install-option.
 cmdoptions.check_install_build_global(options)
DEPRECATION: Location-changing options found in --install-option: ['--install-purelib'] from command line. This configuration may cause unexpected behavior and is unsupported. pip 20.2 will remove support for this functionality. A possible replacement is using pip-level options like --user, --prefix, --root, and --target. You can find discussion regarding this at https://github.com/pypa/pip/issues/7309.
Collecting beautifulsoup4
 Downloading beautifulsoup4-4.8.2.tar.gz (298 kB)
    |████████████████████████████████| 298 kB 2.2 MB/s
Requirement already satisfied: soupsieve>=1.2 in c:\users\me\appdata\local\packages\pythonsoftwarefoundation.python.3.7_qbz5n2kfra8p0\localcache\local-packages\python37\site-packages (from beautifulsoup4) (2.0)
Installing collected packages: beautifulsoup4
   Running setup.py install for beautifulsoup4 ... done
Successfully installed beautifulsoup4

>python3 -m pip list

Package        Version
-------------- ---------
aiohttp        3.5.4
async-timeout  3.0.1
attrs          19.3.0
beautifulsoup4 4.8.2
certifi        2019.9.11
chardet        3.0.4
discord.py     1.2.5
googletrans    2.4.0
idna           2.8
multidict      4.6.1
pip            20.0.2
requests       2.22.0
setuptools     42.0.1
soupsieve      2.0
urllib3        1.25.7
websockets     6.0
yarl           1.3.0

 python3のリストにも載っている。大丈夫そう。
 次に実際にコードを動かしてみる。先ほどはbs4が無いと言われエラーが出ていた。

>python3 natsuru.py

ログインしました

 できた。

おわりに

 今回はbeautifulsoup4のimport問題を扱った。しかし、本記事の解決方法は無理やりな手法であり、今後新たにモジュールをインストールする際に再び困ることが予想される。まだ調べてはいないが、pip3のデフォルトインストール先はconfigをいじることで変更できたりしそう。
 以上でおしまい。


蛇足

色々あったこと。

・Requirement already satisfied: pip in c:\users\me\appdata\local\packages\pythonsoftwarefoundation.python.3.7_qbz5n2kfra8p0\localcache\local-packages\python37\site-packages (20.0.2)

 これは単にアンインストールのし忘れ。まだ上のディレクトリ内に残っている状態で別のディレクトリに再インストールしようとしたのでエラーがでた。pip3 uninstall で解決。

・C:\Users\Me\AppData\Local\Programs\Python\Python37\lib\site-packages\bs4\element.py:16: UserWarning: The soupsieve package is not installed. CSS selectors cannot be used.
'The soupsieve package is not installed. CSS selectors cannot be used.'

 python3実行時に出たエラー。soupsieveが無いと言われた。通常soupsieveはbeautifulsoup4のインストール時に自動で入れてくれるが、ディレクトリ先指定オプションを使用した場合入れてくれないみたい。beautifulsoup4を入れたコマンドを再利用してsoupsieveもインストールして解決。

・DEPRECATION: Location-changing options found in --install-option: ['--install-purelib'] from command line. This configuration may cause unexpected behavior and is unsupported. pip 20.2 will remove support for this functionality. A possible replacement is using pip-level options like --user, --prefix, --root, and --target. You can find discussion regarding this at https://github.com/pypa/pip/issues/7309.

 最後にこれ。ディレクトリ先指定オプションは将来的に削除されるらしい。わしはどうすればいいのだろうか。