【M1 Mac】Python ScrapyがImportErrorで大ハマリ。lxmlなど環境作成し対応した件。
2023.05.24
この記事は最終更新日から1年以上が経過しています。
どもです。
またまた、久々な感じです。
最近はもっぱらプログラミングは、Dart言語ばかりのコーディングだったのですが、ふとPythonのScrapyを使う機会があり、M1 Macで使用しようとしたら大ゴケして対応した話となります。
そういえば、M1Macに移行する以前は、Djangoとか扱っていたが、M1Macに移行してpython環境がスムーズに構築できなかったので諦めた覚えが。。。
取り敢えず、pythonの仮想環境を構築と。
python -m venv .venv source .venv/bin/activate
scrapyをインストールします。
pip install scrapy
scrapy startprojectでテンプレート生成。
scrapy startproject xxxxx
と、エラーが発生。
ImportError: dlopen(〜〜〜〜〜/lxml/etree.cpython-310-darwin.so, ...)
長い旅路の始まりです。
最終的には、githubのソースよりビルドすることで解決はできました。
$ git clone https://github.com/lxml/lxml $ cd lxml $ git checkout tags/lxml-4.9.1 $ python setup.py bdist_wheel $ cd dist/ $ sudo pip install lxml-4.9.1-cp310-cp310-macosx_13_0_arm64.whl
が、それまで色々と奮闘してしまいました。
まず、よく確認してみると、pyenvのpythonではなくsystemのpythonを使用していたので、pyenvで別バージョンのpythonをインストールしてみようと。
pyenv インストール
systemのpythonを使用していたので、pyenvで別バージョンのpythonをインストールしてみる。
pyenv install 3.10.4
ですが、ここでもエラー。
pyenv installで別バージョンのpythonインストールができない状態。
BUILD FAILED (OS X 13.2.1 using python-build 20180424)
ぬお。
python-buildバージョンがなんか古いな。と。
CommandLineToolsを削除し、再インストールを試みました。
sudo rm -rf /Library/Developer/CommandLineTools
xcode-select --install
インストールには時間がかかります。
pyenv install 3.10.4
もう時系列は忘れてしまったのですが。。
zlibやllvmなどもインストールし直したり。。
brew install zlib
$ echo 'export LDFLAGS="-L/usr/local/opt/zlib/lib"' >> ~/.bash_profile $ echo 'export CPPFLAGS="-I/usr/local/opt/zlib/include"' >> ~/.bash_profile $ echo 'export PKG_CONFIG_PATH="/usr/local/opt/zlib/lib/pkgconfig"' >> ~/.bash_profile $ source ~/.bash_profile
色々行ったにも関わらず、ビルドエラーは消えなく、
最終的に解決した内容として、pyenvを再インストールし直したらインストールできるようになりました。。
pyenv アンインストールしインストールし直し。
brew uninstall pyenv
brew install pyenv
再度、3.10.4をインストール
pyenv install 3.10.4
インストールしたバージョンをglobalに設定。
pyenv global 3.10.4
インストールしたバージョンを確認。
pyenv versions system * 3.10.4 (set by /Users/takayamadaisuke/.pyenv/version)
よし完璧。pythonのバージョン確認。
python --version
Python 3.9.4
ほげ。
うーん。。pyenvのpathが通っていないのかどうか。
vim ~/.bash_profile
export PYENV_ROOT="$HOME/.pyenv" export PATH="$PYENV_ROOT/shims:$PATH" eval "$(pyenv init --path)" eval "$(pyenv init -)"
反映
source ~/.bash_profile
と言った感じで、取り敢えずpyenvでバージョンインストールでき設定も完了しました。
python --version
Python 3.10.4
再度、pythonの仮想環境を作り直し、scrapy startprojectを実行。
scrapy startproject xxxxx
エラーは改善されず。。
ImportError: dlopen(〜〜〜〜〜/lxml/etree.cpython-310-darwin.so, ...)
symbol not found in flat namespace '_xsltDocDefaultLoader'
lxml自体も何度もインストールし直したり
$ pip uninstall lxml
$ pip install lxml
キャッシュが効いているのではと、キャッシュ無しでインストールし直したり、
pip --no-cache-dir install lxml
pip --no-cache-dir install scrapy
–no-binaryオプションでインストールし直したり、
$ pip uninstall lxml
$ pip install --no-binary lxml lxml
環境変数設定したり、
RCHFLAGS="-arch arm64" pip install lxml --compile --no-cache-dir
一向にエラーは改善されず、setuptoolsなどもインストールしてみたりと
pip install -U setuptools
なんか、色々行ったのですが駄目だったので、lxmlをソースからビルドしてみることにしました。
冒頭で記述したように、https://github.com/lxml/lxmlをクローンし、tags/lxml-4.9.1
をチェックアウト、python setup.py bdist_wheelでパッケージビルド実行。
git clone https://github.com/lxml/lxml cd lxml
git checkout tags/lxml-4.9.1 python setup.py bdist_wheel
リリースパッケージはこちら。
https://github.com/lxml/lxml/releases
ですが、今度はpython setup.py bdist_wheelでエラーが出てしまう。。
よく見ると、brewパッケージを参照しているパスが以前のパスを参照しているくさい。
Building against libxml2/libxslt in the following directory:/usr/local/Cellar/
Apple Silicon版のHomebrewは /opt/homebrewを利用する形となっているので、/usr/local/Cellar/は必要ないはず。だけど以前のMacよりそのまま移行したせいか、いっぱいある。
思い切って削除してみました。
sudo rm -fr /usr/local/Cellar/
再度libxml2をインストールし直し、
brew uninstall libxml2 brew install libxml2
パスも通す。
export PATH="/opt/homebrew/opt/libxml2/bin:$PATH" export LDFLAGS="-L/opt/homebrew/opt/libxml2/lib" export CPPFLAGS="-I/opt/homebrew/opt/libxml2/include" export PKG_CONFIG_PATH="/opt/homebrew/opt/libxml2/lib/pkgconfig"
参照しているパスは変更されたものの、まだ依然としてエラーが発生する状態。
Building against libxml2/libxslt in the following directory: /opt/homebrew/Cellar/libxml2/2.11.4/lib usage: setup.py [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...] or: setup.py --help [cmd1 cmd2 ...] or: setup.py --help-commands or: setup.py cmd --help
error: invalid command 'bdist_wheel'
うーん。もう少しだと思うが。Cythonが必要ぽいのでインストール。
pip install Cython
wheelパッケージも必要そうなのでインストール。
pip install wheel
再度実行。
python setup.py bdist_wheel
ついに成功。
dist以下にビルド成果物が生成されますので、そちらをインストール。
cd dist/
sudo pip install lxml-4.9.1-cp310-cp310-macosx_13_0_arm64.whl
と、最終的にソースからビルドを行うことによって、M1 Macでも、Python Scrapyパッケージを使用することができました。
長かった。。
最終的なlxmlのインストール方法。
git clone https://github.com/lxml/lxml cd lxml git checkout tags/lxml-4.9.1 python setup.py bdist_wheel cd dist/ sudo pip install lxml-4.9.1-cp310-cp310-macosx_13_0_arm64.whl