Python

Python3でCGIを実行。失敗しやすいポイントも紹介。

2018年7月18日

こんにちは!土門大貴(daikidomon)です。

Pythonで「CGI(Common Gateway Interface)」を使用する方法を紹介します。

初めてCGIを使う人向けに分かりやすく説明しておりますので、

この機会にPythonがWebサーバ上でどのように動作するのか理解しましょう。

Pythonには強力なWeb開発フレームワークとして、

  • Djando
  • Flask
  • Bottle

があります。

基本となるCGIの動作を学ぶことで上記のフレームワークをより理解し使いこなすことが出来ます。

CGI実行環境

今回使用する実行環境は下になります。

  • CentOS 7(KAGOYA VPS)
  • Webサーバ:Apache
  • Python:Version 3.6.5

作成するファイルと配置先

今回のディレクリ構成は以下になります。

-/cgi-bin

└ pyCGI.py

- /html

└ index.html

Apacheをインストールした時のデフォルト設定になります。

以下、Apacheインストール方法です。

LinuxにApacheをインストールする方法

こんにちは!土門大貴(daikidomon)です。 Apecheをインストールする手順について紹介します。 Conten ...

続きを見る

HTMLのフロントページ

今回使用するHTMLのフロントページ「index.html」は以下になります。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>pyCGI</title>
  <head>
  <body>
    <form action="/cgi-bin/pyCGI.py" method="post">
    <input type="text" name="text">
    <input type="submit" name="submit">
  </form>
  </body>
</html>

formタグを使い、「POST」で入力値をCGIに渡します。

PythonのCGIコード

「index.html」から渡された入力値を受け取る「pyCGI.py」は以下になります。

#!/usr/bin/python
# -*- coding: utf-8 -*-
import cgi
import sys
import io

sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
print('Content-Type: text/html; charset=UTF-8\n')
html_body = """
<!DOCTYPE html>
<html>
<head>
</haed>
<body>
<h1>Your input is "%s"</h1>
</body>
</html>
"""

form = cgi.FieldStorage()
text = form.getvalue('text', '')

print(html_body % (text))

1行目の「#!/usr/bin/python」で実行するPythonのパスを設定します。

環境ごとに違うので「which python」で確認しましょう。

3行目の「import cgi」でcgiライブラリをインポートします。

9行目の「Content-Type: text/html; charset=UTF-8\n」はCGIを使う上でのおまじないなので、どのCGIにも記載します。

22,23行目でPOSTされた値を処理して、text変数に格納しています。

CGIファイルに実行権限を付与

pyCGI.py」をサーバに配置したら実行権限を付けましょう。

chmod 755 pyCGI.py

以下実行ログです。

[root@localhost cgi-bin]# chmod 755 pyCGI.py
[root@localhost cgi-bin]# ls -l
total 4
-rwxr-xr-x. 1 root root 497 Jul 17 20:40 pyCGI.py

実行権限を付与しない場合、以下の500エラーとなるでの注意してください。

Pythonファイルに実行権限がないと500エラーが発生する画面

エラーログには「Permission denied: exec of '/xxx/xxx/www/cgi-bin/pyCGI.py'」と出力されます。

PythonのCGIを実行してみる

「index.html」を格納したURLにアクセスしてみましょう。

表示されたら下のように「Test」と入力してみましょう。

PythonのCGIの動作確認

下のように入力した文字列が表示されたら正常に動作しています。

PythonのCGIで正常に入力した値を表示

マルチバイト文字列(日本語)がCGIで動作しない場合の対処方法

マルチバイト文字列を「POST」した時に正常に動作しない環境が存在します。

エラーログを確認しますと「UnicodeEncodeError: 'ascii' codec can't encode characters in position 」が表示されています。

これはCGIの実行ユーザの環境変数に「LANG」が設定されていないため発生します。

この問題の対象方法は、明示的にPythonが出力する文字列を「UTF-8」にすれば解決します。

#!/usr/bin/python
# -*- coding: utf-8 -*-
import cgi
import sys
import io

sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
print('Content-Type: text/html; charset=UTF-8\n')
html_body = """
<!DOCTYPE html>
<html>
<head>
</haed>
<body>
<h1>Your input is "%s"</h1>
</body>
</html>
"""

form = cgi.FieldStorage()
text = form.getvalue('text', '')

print(html_body % (text))

4,5行目で「sys」と「io」ライブラリをインポートします。

8行目で標準出力の文字コードを「UTF-8」で出力するように設定することで、

マルチバイト文字列も正常に出力することができます。

下にように表示されれば正常に動作しています。

PythonのCGIでマルチバイト文字列を正常に処理する例

関連記事

-Python

Copyright© スタートアップIT企業社長のブログ , 2020 All Rights Reserved.