こんにちは!土門大貴(daikidomon)です。
Pythonで「CGI(Common Gateway Interface)」を使用する方法を紹介します。
初めてCGIを使う人向けに分かりやすく説明しておりますので、
この機会にPythonがWebサーバ上でどのように動作するのか理解しましょう。
Pythonには強力なWeb開発フレームワークとして、
- Djando
- Flask
- Bottle
があります。
基本となるCGIの動作を学ぶことで上記のフレームワークをより理解し使いこなすことが出来ます。
Contents
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エラーとなるでの注意してください。
エラーログには「Permission denied: exec of '/xxx/xxx/www/cgi-bin/pyCGI.py'」と出力されます。
PythonのCGIを実行してみる
「index.html」を格納したURLにアクセスしてみましょう。
表示されたら下のように「Test」と入力してみましょう。
下のように入力した文字列が表示されたら正常に動作しています。
マルチバイト文字列(日本語)が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」で出力するように設定することで、
マルチバイト文字列も正常に出力することができます。
下にように表示されれば正常に動作しています。