xmlのparseで利用するためにlxmlをインストールする

背景

以前はxmlのparseにxml.etree.ElementTreeを利用しました。実際に利用したところ、ファイルサイズが大きめのXMLを読み込んでループを回したところで、out of memoryになり、停止してしまいました。

なにか別のライブラリはないかなと思って探したところlxmlというパッケージが見つかったのでそれを利用してみようと思います。

インストール

pipでインストールします。Pipfilelxml = "*"を追加して、インストールします。

1
2
3
4
5
6
7
8
9
$ docker-compose run --rm web python -m pipenv install --system --skip-lock
Creating test_site_web_run ... done
Installing dependencies from Pipfile...
🐍 ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 1/1 — 00:00:00
An error occurred while installing lxml! Will try again.
Installing initially failed dependencies...
(中略)
[pipenv.exceptions.InstallError]: error: command 'gcc' failed: No such file or directory
...

エラーが起こってしまいました。'gcc' failed: No such file or directoryというエラーになっているので確認してみると、gccがインストールされていません。

gccのインストール

Dockerfileに以下の1行を追記します。

1
RUN apk add gcc

再ビルドします。

1
2
3
4
5
6
7
$ docker-compose build                                                     
Building web
[+] Building 23.5s (12/12) FINISHED
(中略)
#12 20.56 [pipenv.exceptions.InstallError]: /tmp/xmlXPathInitzi6405c3.c:1:10: fatal error: libxml/xpath.h: No such file or directory
#12 20.56 [pipenv.exceptions.InstallError]: 1 | #include "libxml/xpath.h"
...

xpath.hがないということです。調べてみると、libxslt-devというパッケージが必要とのことなので、以下のように修正してインストールします。

1
RUN apk add gcc libxslt-dev

ビルドします。

1
2
3
4
5
6
7
8
9
$ docker-compose build
Building web
(中略)
#12 11.11 [pipenv.exceptions.InstallError]: /usr/local/include/python3.9/Python.h:11:10: fatal error: limits.h: No such file or directory
#12 11.11 [pipenv.exceptions.InstallError]: 11 | #include <limits.h>
(中略)
#12 11.11 [pipenv.exceptions.InstallError]: /usr/include/libxml2/libxml/tree.h:15:10: fatal error: stdio.h: No such file or directory
#12 11.11 [pipenv.exceptions.InstallError]: 15 | #include <stdio.h>
...

また失敗しました。ちょっとわからないので、調べてみます。

musl-devというパッケージが必要とのことなので、そちらもインストールします。

1
RUN apk add gcc libxslt-dev musl-dev

もう一度ビルドします。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ docker-compose build
Building web
[+] Building 185.8s (13/13) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 260B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/python:3.9.7-alpine 2.5s
=> [1/8] FROM docker.io/library/python:3.9.7-alpine@sha256:eb1b2038f12c8916be54329319a625de2dfec4266b718efdb798cc149b342a2f 0.0s
=> [internal] load build context 0.1s
=> => transferring context: 18.50kB 0.1s
=> CACHED [2/8] RUN apk update 0.0s
=> [3/8] RUN apk add gcc libxslt-dev musl-dev 4.6s
=> [4/8] RUN mkdir /code 0.4s
=> [5/8] WORKDIR /code 0.0s
=> [6/8] ADD . /code/ 0.1s
=> [7/8] RUN pip install pipenv 8.1s
=> [8/8] RUN python -m pipenv install --system --skip-lock 168.1s
=> exporting to image 1.8s
=> => exporting layers 1.8s
=> => writing image sha256:499cdeca8be5a7281b86e0e691498568fef3dec05495c64552e99aea0322d53e 0.0s
=> => naming to docker.io/library/test_site_web 0.0s

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them

無事ビルドできました!

まとめ

lxmlを利用するには、gcc, libxslt-dev, musl-devが必要でした。

次回はlxmlを使ってparseする処理を実装していきたいと思います。

参考図書