概要
PythonのコードでCGI(Common Gateway Interface)によってHTMLをする方法の基本。
基本の枠組み
コード例
例えば以下の内容をindex.py
として準備。
- SheBangでPythonの場所を指定
Content-Type
を出力して1行空ける- 出力内容を記述
1 2 3 4 5 |
#!/usr/bin/python3.6 print('Content-Type: text/html') print('') print('Python CGI Test') |
HTTPのヘッダーで最低限Content-Type
を出力し、ボディーとの間に空行が1行必要。これがないと、500エラーとなり、ログには以下の様に記録される。
1 |
[cgi:error] [pid 30090] [client 192.168.33.1:65449] malformed header from script 'index.py': Bad header: Python CGI Test |
コードのモード確認
ファイルがrootの実行権限を持っていること。実行権限がない場合はchmod 755
かchmod +x
で設定する。
コードの配置
cgi実行用のディレクトリーにファイルを配置。Apacheの場合例えば/var/www/cgi-bin
など。
ブラウザ表示
URLで[ホスト]/cgi-bin/index.py
を指定すると、ブラウザーにPython CGI Test
と表示される。
HTML出力例
ASCII出力
基本の枠組みの出力に、以下の様にタグを加えると要素として表示される。
1 2 3 4 5 6 |
#!/usr/bin/python3.6 print('Content-Type: text/html') print('') print('<h1>Python CGI Test</h1>') print('<p>Python CGI Test</p>') |
UTF-8出力
上のコードの一部を日本語にしてみる。
1 2 3 4 5 6 |
#!/usr/bin/python3.6 print('Content-Type: text/html') print('') print('<h1>Python CGI test</h1>') print('<p>Python CGI テスト</p>') |
ところがこれをブラウザーで確認すると、h1
要素は表示されるがp
要素が全く表示されない。ソースを確認してもh1
要素の行が表示されるだけ(このコードをコンソールで実行すると、h1
要素の行もp要素の行も表示される)。
これを解決するには、ソースコードでio.TextIOWrapper
を実行するとよいらしい。
1 2 3 4 5 6 7 8 9 10 |
#!/usr/bin/python3.6 import sys, io sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') print('Content-Type: text/html') print('') print('<h1>Python CGI test</h1>') print('<p>Python CGI テスト</p>') |
上記の2行を追加すると、無事日本語まで表示された。
HTML出力
コンテンツを以下の様にHTMLの構造にして出力する。title
要素も機能して、タブの表示が変更された。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#!/usr/bin/python3.6 import sys, io sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') html = ''' <html> <head> <title>Python CGI</title> </head> <body> <h1>Python CGI test</h1> <p>Python CGI HTMLテスト</p> </body> </html> ''' print('Content-Type: text/html') print('') print(html) |
ループの利用例
以下のコードでは、見栄えは良くないがfor
ループでli要素を生成している。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
#!/usr/bin/python3.6 import sys, io sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') html_head = ''' <head> <title>Python CGI</title> </head> ''' html_body = ''' <h1>Python CGI test</h1> <p>Python CGI HTMLテスト</p> ''' print('Content-Type: text/html') print('') print('<html>') print(html_head) print('<body>') print(html_body) print('<ol>') for i in range(5): print('<li>{}番目のli要素</li>'.format(i + 1)) print('</ol>') print('</body') print('</html>') |
出力に以下が加わる。
- 1番目のli要素
- 2番目のli要素
- 3番目のli要素
- 4番目のli要素
- 5番目のli要素
Apacheの設定
今回は/etc/httpd/conf/httpd.conf
のデフォルトのままでcgi-script
の設定を加えていないが、そのままで適切に実行された。