Python3のCGIで日本語を出力する

Raspberry PiにインストールしたApache2でPython3のCGIを動かそうとしてはまりましたので、対処した方法をメモしておきます。

目次

  1. pyenvを使う場合のシバン
  2. Apache2のエラーログを見てみる
  3. Pythonの標準出力をエンコードする

pyenvを使う場合のシバン

スクリプトファイルの最初のシャープとビックリマークで始まる行をシバンといって、この行でスクリプトの実行ファイルを指定します。

pyenvでインストールしたPythonを使う場合は、インストールしたPythonをシバンに指定します。

#!/home/pi/.pyenv/versions/3.6.3/bin/python

print("Content-type: text/html; charset=UTF-8")
print("")
print("<html>")
print("<head>")
print("<title>test</title>")
print("</head>")
print("<body>テスト</body>")
print("</html>")

これでウェブブラウザでCGIにアクセスするとスクリプトが実行されるのですが、ブラウザには何も表示されません。 ページのソースコードを表示させると、bodyタグ以下が無い状態になります。

Apache2のエラーログを見てみる

Apache2のエラーログは /var/log/apache2/error.log に記録されています。 ログを見てみると、こんな感じになっていました。

$ cat /var/log/apache2/error.log

エラーメッセージだけを抜き出すとこんな感じ。

Traceback (most recent call last):: /home/pi/www/cgi-bin/test.py
  File "/home/pi/www/cgi-bin/test.py", line 13, in <module>: /home/pi/www/cgi-bin/test.py
    print("<body>\\u30c6\\u30b9\\u30c8</body>"): /home/pi/www/cgi-bin/test.py
UnicodeEncodeError: 'ascii' codec can't encode characters in position 6-8: ordinal not in range(128): /home/pi/www/cgi-bin/test.py

日本語をエンコードできなかったようです。 Raspbian liteでApache2を実行するユーザーはwww-dataなのですが、そのロケールがja_JP.UTF-8ではないからなのだと思うのですが、どうでしょう。

Pythonの標準出力をエンコードする

Python3の方で標準出力をエンコードしてみます。

#!/home/pi/.pyenv/versions/3.6.3/bin/python
import sys
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

print("Content-type: text/html; charset=UTF-8")
print("")
print("<html>")
print("<head>")
print("<title>test</title>")
print("</head>")
print("<body>テスト</body>")
print("</html>")

sys.stdoutで始まる行で標準出力のエンコードを指定しています。 これでブラウザに「テスト」と表示されます。

公開日

広告