「PythonでHTTTPクライアントを利用したい」
「Python標準ライブラリのurllibだけでは役不足だ」
このような場合は、urllib3が利用できます。
この記事では、urllib3について解説しています。
本記事の内容
- urllib3とは?
- urllib3のシステム要件
- urllib3のインストール
- urllib3の動作確認
それでは、上記に沿って解説していきます。
urllib3とは?
urllib3は、HTTPクライアントです。
ただ、Pythonの標準ライブラリにはHTTPクライアントが備わっています。
urllibパッケージとして、デフォルトで利用可能です。
それなのになぜurllib3が必要なのでしょうか?
それは、urllibでは物足りないということです。
その不足部分を補うために、urllib3が存在すると言えます。
urllib3のライブラリとしての特徴は、以下。
- スレッドの安全性
- コネクションプーリング
- クライアントサイドでのTLS/SSL検証
- マルチパートエンコーディングによるファイルアップロード
- リクエストの再試行やHTTPリダイレクトに対応するヘルパー
- gzip、deflate、およびbrotliエンコーディングのサポート
- HTTP およびSOCKSのプロキシをサポート
上記の特徴により、urllib3はHTTP通信では欠かせません。
実際、SeleniumやRequestsなどの有名ライブラリにおいて利用されています。
urllib3と依存関係のあるライブラリは、他にも数多く存在しています。
そのため、知らず知らずにurllib3のお世話になっている可能性があります。
以上、urllib3について説明しました。
次は、urllib3のシステム要件を確認します。
urllib3のシステム要件
現時点(2021年10月)でのurllib3の最新バージョンは、1.26.7となります。
この最新バージョンは、2021年9月23日にリリースされています。
サポートOSに関しては、以下を含むクロスプラットフォーム対応です。
- Windows
- macOS
- Linux
サポート対象となるPythonのバージョンは、以下となります。
- Python 2.7
- Python 3.5
- Python 3.6
- Python 3.7
- Python 3.8
- Python 3.9
- Python 3.10
幅広くサポートしていることは、素晴らしいことではあります。
ただ、次のPython公式開発サイクルをご覧ください。
バージョン | リリース日 | サポート期限 |
3.6 | 2016年12月23日 | 2021年12月23日 |
3.7 | 2018年6月27日 | 2023年6月27日 |
3.8 | 2019年10月14日 | 2024年10月 |
3.9 | 2020年10月5日 | 2025年10月 |
3.10 | 2021年10月4日 | 2026年10月 |
Python自体が、3.7以降はサポートしない宣言をしています。
Python 3.6は、2021年の年末で終了です。
urllib3ほどの影響力があれば、是非とも公式サイクルに従って欲しいと思います。
そうすれば、Python 2や古いPythonが使われ続けることも減るでしょう。
まとめると、urllib3は基本的にはどんな環境でも動くということです。
これは、非常にありがたいことでもありますけどね。
以上、urllib3のシステム要件の説明でした。
次は、urllib3をインストールします。
urllib3のインストール
検証は、次のPythonバージョンで行います。
>python -V Python 3.10.0
まずは、現状のインストール済みパッケージを確認しておきます。
>pip list Package Version ---------- ------- pip 21.3 setuptools 58.2.0
次にするべきことは、pipとsetuptoolsの更新です。
pipコマンドを使う場合、常に以下のコマンドを実行しておきましょう。
python -m pip install --upgrade pip setuptools
では、urllib3のインストールです。
urllib3のインストールは、以下のコマンドとなります。
pip install urllib3
インストールは、一瞬で終わります。
では、どんなパッケージがインストールされたのかを確認しましょう。
>pip list Package Version ---------- ------- pip 21.3 setuptools 58.2.0 urllib3 1.26.7
依存するパッケージは、ありません。
機能に加えて、このような部分でもurllib3が多くのライブラリに支持(依存)されるのでしょう。
以上、urllib3のインストールについて説明しました。
最後は、urllib3の動作確認を行います。
urllib3の動作確認
urllib3の動作確認として、あるWebページのHTTPヘッダーを取得します。
import urllib3 import json http = urllib3.PoolManager() r = http.request('GET', 'https://example.com/') print(json.dumps(dict(r.headers), ensure_ascii=False, indent=4, sort_keys=True, separators=(',', ': ')))
今回は、Example Domainを対象にしています。
Chrome DevTools(デベロッパーツール)で確認した場合は、以下。
そして、サンプルコードで実行した結果は以下。
見やすいようにjson.dumpsやdictを用いています。
{ "Accept-Ranges": "bytes", "Age": "466861", "Cache-Control": "max-age=604800", "Content-Length": "1256", "Content-Type": "text/html; charset=UTF-8", "Date": "Sun, 17 Oct 2021 03:54:48 GMT", "Etag": "\"3147526947\"", "Expires": "Sun, 24 Oct 2021 03:54:48 GMT", "Last-Modified": "Thu, 17 Oct 2019 07:18:26 GMT", "Server": "ECS (sab/5693)", "Vary": "Accept-Encoding", "X-Cache": "HIT" }
Content-Lengthの値が異なるのが気になります。
Content-Lengthなんて、urllib3を使った場合は2倍になっています。
Ageに関しては、プロキシーの利用が異なるのでしょうかね。
この値に関しては、異なることもあり得るでしょうと言うレベルです。
そして、最も気になったのは「content-encoding」がurllib3ではないことです。
圧縮せずにプレーンな状態で通信しているということなのでしょう。
そのことが原因となり、Content-Length2倍事件が発生しているのかもしれません。
では、それを確かめるためにHTTPリクエストヘッダーを設定してみましょう。
設定したコードは、以下。
「Accept-Encoding」をChromeと同じ設定にしています。
import urllib3 import json headers = { 'Accept-Encoding': 'gzip, deflate, br' } http = urllib3.PoolManager() r = http.request('GET', 'https://example.com/', headers=headers) print(json.dumps(dict(r.headers), ensure_ascii=False, indent=4, sort_keys=True, separators=(',', ': ')))
上記コードの実行結果は、以下。
{ "Accept-Ranges": "bytes", "Age": "196305", "Cache-Control": "max-age=604800", "Content-Encoding": "gzip", "Content-Length": "648", "Content-Type": "text/html; charset=UTF-8", "Date": "Sun, 17 Oct 2021 04:10:07 GMT", "Etag": "\"3147526947\"", "Expires": "Sun, 24 Oct 2021 04:10:07 GMT", "Last-Modified": "Thu, 17 Oct 2019 07:18:26 GMT", "Server": "ECS (sab/5697)", "Vary": "Accept-Encoding", "X-Cache": "HIT" }
Content-Encodingが出ました。
Content-Lengthも半分に圧縮されました。
urllib3の動作確認としては、これで十分でしょう。
以上、urllib3の動作確認の説明でした。