「国際化ドメイン名 (IDNA)をPunycode(ピュニコード)に変換する必要がある」
「日本語ドメインの変換処理をPythonで行いたい」
このような場合は、idnaライブラリが利用できます。
この記事では、idnaについて解説しています。
本記事の内容
- idnaとは?
- idnaのシステム要件
- idnaのインストール
- idnaの動作確認
それでは、上記に沿って解説していきます。
idnaとは?
idnaは、IDNAプロトコルに対応したPythonライブラリです。
機能としては、国際化ドメイン名 (IDNA)をPunycode(ピュニコード)に変換します。
もちろん、 Punycodeを国際化ドメイン名に変換することも可能です。
実は、Pythonは標準でIDNAプロトコルに対応しています。
Python標準ライブラリに付属する「encoding.idna」モジュールで対応可能です。
しかし、「encoding.idna」は古いIDNA仕様(RFC 3490)にしか対応していません。
つまり、最新のIDNA仕様には未対応ということです。
そのため、「encoding.idna」には少し問題があると言えます。
その問題は、次のページ説明されています。
「UNICODE IDNA COMPATIBILITY PROCESSING」
https://unicode.org/reports/tr46/
そのような問題があるからこそ、idnaを利用するライブラリが数多く存在しているのでしょう。
以上、idnaについての説明でした。
次は、idnaのシステム要件を確認します。
idnaのシステム要件
現時点(2021年10月)でのidnaの最新バージョンは、3.3となります。
この最新バージョンは、2021年10月13日にリリースされています。
サポートOSに関しては、以下を含むクロスプラットフォーム対応です。
- Windows
- macOS
- Linux
サポート対象となるPythonのバージョンは、以下となります。
- Python 3.5
- Python 3.6
- Python 3.7
- Python 3.8
- Python 3.9
- Python 3.10
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月 |
本来なら、idnaはPython 3.5と3.6への対応を打ち切ってもよいでしょう。
以上より、idnaのシステム要件はPython 3.5以降だけと言えます。
これだけ守れば、最新のPython 3.10でもインストール可能です。
なお、Python 3.10のインストールについては次の記事で解説しています。
以上、idnaのシステム要件を説明しました。
次は、idnaをインストールします。
idnaのインストール
検証は、次の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
では、idnaのインストールです。
idnaのインストールは、以下のコマンドとなります。
pip install idna
インストールは、一瞬で終わります。
では、どんなパッケージがインストールされたのかを確認しましょう。
>pip list Package Version ---------- ------- idna 3.3 pip 21.3 setuptools 58.2.0
依存するパッケージは、ゼロです。
これなら、どんな環境にでも気軽にidnaを導入できます。
以上、idnaのインストールについて説明しました。
最後は、idnaの動作確認を行います。
idnaの動作確認
idnaとPython標準(encoding.idnaモジュール)との違いを確認します。
そのための動作確認用のコードは、以下。
import idna text = "●●●.●●" # Python標準 print("---Python標準---") decode_text_python = text.encode("idna") print(decode_text_python) print(decode_text_python.decode("idna")) # idnaライブラリ print("---idnaライブラリ---") decode_text_idna = idna.encode(text) print(decode_text_idna) print(idna.decode(decode_text_idna))
「text」に、国際化ドメイン名 (IDNA) を設定します。
今回は、次の2つで確認します。
- 日本語.jp
- faß.de
それぞれを設定した場合におけるコードの実行結果は、以下。
日本語.jp
---Python標準--- b'xn--wgv71a119e.jp' 日本語.jp ---idnaライブラリ--- b'xn--wgv71a119e.jp' 日本語.jp
この場合は、同じようにエンコード/デコードできています。
同じPunycodeとなっています。
faß.de
---Python標準--- b'fass.de' fass.de ---idnaライブラリ--- b'xn--fa-hia.de' faß.de
この場合は、結果が異なります。
まず、Punycodeの時点で異なっています。
そうなると、デコードした結果も異なります。
Python標準だと、元に戻せすことができていません。
Python標準を利用したら、適切にエンコード/デコードできないということです。
「faß.de」は、次のページの「Table 1. Deviation Characters」を参考にしています。
https://unicode.org/reports/tr46/
この結果を見ると、idnaライブラリを利用すべきとなりますね。
idnaライブラリに依存するライブラリが多いのも納得です。
以上、idnaの動作確認の説明でした。