概要
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の設定を加えていないが、そのままで適切に実行された。