Pythonでモジュールを使いたかったのでpipとか使ってインストールするまでのメモとか躓いた所とか

概要・やりたかった事

※ 自環境は raspberryPi 3 B+ マシン上である という事を先に明言しておきます
( Debian系OSなら、使いまわせそうな話かも )

Python (厳密にはPython3) でスクレイピングというものをしたかった。
ソースコード中で、

import requests
from bs4 import BeautifulSoup

のような感じで書けば、スクレイピングが楽になるモジュール(ライブラリみたいなもの)がPython内で使える。 しかし、これらはPythonインストール時に元からついてくるものではなく、手動で導入する必要があった。

「Linux系マシンに不慣れ + 頭のリソースはコーディングに割きたい」という事もあり、 とりあえず一度導入してしまえばOKそうなモジュール周りの導入手順や覚書をまとめている感じです。

先に結論 / テンプレコマンド

※ 注意事項とか細かい解説とか一切すっ飛ばした(自分用の)手順だけ先に書きます

sudo apt install python3-pip で Python3 用 pip インストール
成功すれば pip コマンドが使えるので、
python3 -m pip install beautifulsoup4 とか
python3 -m pip install requests とかで、欲しいモジュールを導入

おわり。
↓ 以下、通常の解説などの本文↓

Python のバージョンと pip

Pythonにはメジャーなバージョンがあるようです。(執筆時点では 1,2,3まで)
RaspberryPi 3 B+上では、python としてコマンドを叩くと Python2 として起動するようです。 自分は明示的に Python3 を使いたかったので、そちらのバージョン前提でプログラム書いてたり動かしていたりしました。

pip ってやつを使えるようにする

pip コマンドというのがあります。Python用のパッケージ管理ツール だそうで。
この pip をインストールする事で「使いたいパッケージ(モジュールとか)を楽にインストール・管理する権利」が行使できる。
つまり雑に言えば「Pythonで外部のモジュール使いたければ、まずは pip 機能を導入してね!」という解釈。

ちなみにですが、この pip も Python用のパッケージプログラム という扱いっぽいです。pipパッケージを使って他のパッケージやモジュールを導入・管理してるっていう事なんですね。

pip を知るうえで留意してほしいのは、それぞれの pythonのバージョンに、専用の pip が個別に割り振られている という事

雑な概念ツリーを書くと多分こんな感じ?

Python2
├元から入っているモジュールX
├元から入っているモジュールY
├Python2用のpipモジュール # ←これを先に入れる
├pipで入れた外部モジュールA
└pipで入れた外部モジュールB..

Python3
├元から入っているモジュールX
├元から入っているモジュールY
├Python3用のpipモジュール # ←これを先に入れる
├pipで入れた外部モジュールA
└pipで入れた外部モジュールB..

で、まだ pip が導入されていなければ apt でインストールします。 自分は Python3 でモジュールを使いたかったので、必然的に Pyhton3 用の pip を導入する事となりました。 ちなみに Python (ここでいうPython2) 用の pip は自環境ですと元から入っていたような気がします。

pipが(各々)付属されているかどうか確認

python -m pip -V
python2 -m pip -V
python3 -m pip -V

higehito@raspberrypi:~ $ python -m pip -V
pip 19.3.1 from /usr/local/lib/python2.7/dist-packages/pip (python 2.7)

higehito@raspberrypi:~ $ python3 -m pip -V
pip 18.1 from /usr/lib/python3/dist-packages/pip (python 3.7)

# ↓ python3 用 pip 未導入の場合はこんな反応
higehito@raspberrypi:~ $ python3 -m pip -V
/usr/bin/python3: No module named pip

Python3 用の pip をインストールする

方法1

sudo apt install python3-pip
Python3 用の pip をインストール。
sudo を付けないと、

E: Could not open lock file /var/lib/dpkg/lock-frontend - open (13: Permission denied)
E+ : Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), are you root?

みたいな感じで怒られました

方法2

  1. wget https://bootstrap.pypa.io/get-pip.py で get-pip.py というPython用プログラムを任意の場所にDL
  2. sudo python3 get-pip.py で そのままDLした get-pip.pyをPython3で実行する(=インストール処理の効果が得られる)
    • sudo で行わないと、Consider using the `--user` option or check the permissions. みたいに怒られるかも?

方法2 に関しては、
sudo python get-pip.py
sudo python3 get-pip.py との実行で意味合いが違ってきます。
後者のコマンドでなければ、(自環境では) Pyhton3 用 pip はインストールされません

方法2 sudo python3 get-pip.py 実行時のログ

higehito@raspberrypi:~ $ sudo python3 get-pip.py
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Collecting pip
  Downloading https://files.pythonhosted.org/(長いURLなので省略)
Installing collected packages: pip
Successfully installed pip-19.3.1

ちなみに sudo python get-pip.py (ここで言うPython2) で実行した場合のログ。

higehito@raspberrypi:~ $ sudo python get-pip.py
DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7. More details about Python 2 support in pip, can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Collecting pip
  Using cached https://www.piwheels.org/simple/pip/pip-19.3.1-py2.py3-none-any.whl
Installing collected packages: pip
  Found existing installation: pip 19.3.1
    Uninstalling pip-19.3.1:
      Successfully uninstalled pip-19.3.1
Successfully installed pip-19.3.1

Python2 はサポートが終わる(終わった)らしく、敢えて Python(Python2)用のpipをインストールしようとすると、こんな感じの英文もログに表示されていました。

廃止:Python 2.7は、2020年1月1日にサポートが終了します。Python2.7は、それ以降はメンテナンスされないため、アップグレードしてください。 pipの将来のバージョンでは、Python 2.7のサポートが廃止される予定です。 pipでのPython 2サポートの詳細については、https://pip.pypa.io/en/latest/development/release-process/#python-2-supportを参照してください。

インストールした(されている) pip を確認してみる

apt list --installed | grep python
apt list --installed | grep pip
dpkg -l | grep python
dpkg -l | grep pip

higehito@raspberrypi:~ $ apt list --installed | grep pip
(中略)
python-pip-whl/testing,now 18.1-5+rpt1 all [installed,automatic]
python3-pip/testing,now 18.1-5+rpt1 all [installed]

こんな感じで、コマンドを通して python や pip という文字列でインストールされているものを抽出して探ってみると、何となく「どれが既に導入されているか」等は掴めるかもしれません。

とはいえ、一応こちらのコマンドのほうがシンプルで良さそうですね
python3 -m pip -V
pip --version

自環境ですと、2つのコマンドの応答内容はどちらも以下のようになっています。

pip 19.3.1 from /usr/local/lib/python3.7/dist-packages/pip (python 3.7)

欲しいモジュールを導入する

これで (Python3用の) pip が使えるようになりました。
今度はこの pip を用いて、使いたいモジュールをマシン内に落とし込んでいきます

インストールコマンド

python3 -m pip install requests
python3 -m pip install beautifulsoup4
ないし
sudo python3 -m pip install requests
sudo python3 -m pip install beautifulsoup4

このコマンド例では Requests および Beautiful Soup という、自分がスクレイピングを行うにあたって利用したモジュールをインストールしています。

pip install [パッケージ名] でも、(自環境なら)同じ効果が得られるのですが、これだと環境によっては Python(Python2)用のpip で実行される 場合があるかもしれません(?) まぁ明示的に「Pyhton3 の pip でシクヨロ~」とした方が、混乱や間違いも減りそうだったので先のコマンドで実行しています。

モジュールのリストを確認

python3 -m pip list で、Python3 用 pip にて管理・インストールしたモジュールのリストを確認することができます。
pip list でも人によっては同じ効果が得られます。

実行すると、こんな感じでずらーっと出てきます。

higehito@raspberrypi:~ $ python3 -m pip list
Package        Version
-------------- ---------
(前略)
beautifulsoup4 4.8.2
(中略)
requests       2.21.0
(以下略)

躓いてしまった例

自分が躓いてしまった例を持ち出すと、外部モジュールを利用して動く .pyプログラムを書いて
sudo python3 ./hogehoge.py のような感じで Python3 にて実行させても

Traceback (most recent call last):
  File "hogehoge.py", line 10, in <module>
    from bs4 import BeautifulSoup
ModuleNotFoundError: No module named 'bs4'

のように「そんなライブラリない」と怒られる事がありました。

ググって考えなしにコピペしたコマンドでホイホイ進めていた為、 実行時の一般ユーザーと、sudoを用いた権限で実行する場合とで、それぞれ使われるモジュールの場所が異なるケースがあった様です。

これにより
python3 ./hogehoge.py
sudo python3 ./hogehoge.py
のように実行ユーザーが異なる場合、仮に片方のユーザーでしかモジュールをインストールしておかなかった場合に

「あっれー、この前 pip でモジュールインストールしたのになー、Python3 にそんなモジュールねえぞって怒られるな~?」

みたいな事が起きて、一度コケた事がありました。 ( 理解を深めるため、この記事を書いた節が大きいです )

その時の状態なのですが、python3 -m pip を用いて、beautifulsoup4 のモジュールを sudo ありなし2パターンでアンインストールしようとしたときのログを見比べると明確な違いがありました。

sudo のあるなしで、モジュールの場所が異なっている。

higehito@raspberrypi:~ $ python3 -m pip uninstall beautifulsoup4
Uninstalling beautifulsoup4-4.8.2:
  Would remove:
    /home/higehito/.local/lib/python3.7/site-packages/beautifulsoup4-4.8.2.dist-info/*
    /home/higehito/.local/lib/python3.7/site-packages/bs4/*
Proceed (y/n)? n
higehito@raspberrypi:~ $ sudo python3 -m pip uninstall beautifulsoup4
Uninstalling beautifulsoup4-4.8.2:
  Would remove:
    /usr/local/lib/python3.7/dist-packages/beautifulsoup4-4.8.2.dist-info/*
    /usr/local/lib/python3.7/dist-packages/bs4/*
Proceed (y/n)? n

一度、それぞれの権限で Python3 の pip から 該当モジュールをアンインストールしました。
python3 -m pip uninstall beautifulsoup4
sudo python3 -m pip uninstall beautifulsoup4

その後 sudo pip install beautifulsoup4 決め打ちで、改めてモジュールをインストールし、若干付けた知識を活かして諸々を検証。解決に至りました。

(既にインストールされている状態で) 以下4パターンで実際に触ってみたのですが、どうやら pip を持ちいて sudo ありなしでインストールする場合、格納される場所に若干の違いが出るようです。

higehito@raspberrypi:~ $ sudo python3 -m pip install beautifulsoup4
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Requirement already satisfied: beautifulsoup4 in /usr/local/lib/python3.7/dist-packages (4.8.2)
Requirement already satisfied: soupsieve>=1.2 in /usr/local/lib/python3.7/dist-packages (from beautifulsoup4) (1.9.5)

higehito@raspberrypi:~ $ python3 -m pip install beautifulsoup4
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Requirement already satisfied: beautifulsoup4 in /usr/local/lib/python3.7/dist-packages (4.8.2)
Requirement already satisfied: soupsieve>=1.2 in ./.local/lib/python3.7/site-packages (from beautifulsoup4) (1.9.5)

higehito@raspberrypi:~ $ sudo pip install beautifulsoup4
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Requirement already satisfied: beautifulsoup4 in /usr/local/lib/python3.7/dist-packages (4.8.2)
Requirement already satisfied: soupsieve>=1.2 in /usr/local/lib/python3.7/dist-packages (from beautifulsoup4) (1.9.5)

higehito@raspberrypi:~ $ pip install beautifulsoup4
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Requirement already satisfied: beautifulsoup4 in /usr/local/lib/python3.7/dist-packages (4.8.2)
Requirement already satisfied: soupsieve>=1.2 in ./.local/lib/python3.7/site-packages (from beautifulsoup4) (1.9.5)

自分が Python3 を導入するときに何かやらかしてしまっただけなのかもしれませんし、もともとそういうものだったのかもしれません。 とりあえず、.py の実行においての sudo あるなしで、意図したモジュールを参照できない問題は (なんとなく)原因が分かったので、ヨシ!