Help us understand the problem. What is going on with this article?

python でお気楽Webサーバを構築してCGIのテスト。

More than 1 year has passed since last update.

はじめに

phtonを使ってお気楽にWebサーバを構築してみます。

  • Webサーバ用のドキュメントルートの作成
  • index.html の作成
  • Webサーバの起動
  • ブラウザで確認
  • CGIオプションを付けてWebサーバの起動
  • CGIの動作確認
  • POST/GETでCGIにデータの引き渡し確認

という手順で構築してみます。

前提

python3環境が構築されていること。
OSにはWindows10を利用する。

Webサーバ用のドキュメントルートの作成

どこに作成してもいいです。
適当に python_http_server などという名前のフォルダを作成してみましょう。

C:\> cd \
C:\> mkdir python_http_server
C:\> cd python_http_server
C:\python_http_server>

index.html の作成

C:\python_http_server> 直下に index.html を作成する。

index.html
<html>
<head>
<title>
Title: Hello Python World
</title>
</head>
<body>
<h1>
Hello Python World
</h1>
</body>
</html>

このように見えます。

C:\python_http_server>dir/w
 ドライブ C のボリューム ラベルは Windows です
 ボリューム シリアル番号は xxxx です

 C:\python_http_server のディレクトリ

[.]          [..]         index.html
               1 個のファイル                  97 バイト
               2 個のディレクトリ  xxxx バイトの空き領域

Webサーバの起動

python には標準でWebサーバライブラリが存在します。
ドキュメントルートとして作成済のC:\python_http_server で以下のコマンドを実行します。

C:\python_http_server>python -m http.server 8080

※ポート番号を省略した場合デフォルト値は8000です。

python3は http.server ですが、python2 だとコマンドが異なります。

python -m SimpleHTTPServer 8080

ブラウザで確認

http://localhost:8080 にアクセスしてみます。

index_html.png

と出力されました。

なお Microsoft Edgeではセキュリティの観点からlocalhostというURLは標準では見られないので about:flags にアクセスして解除する必要があるります。

about_flags_setting.png

変更してもダメな場合は、Chromeなど別のブラウザで確認してください。

CGI の実行

python3 でCGIを作成して実行させる場合は、

C:\python_http_server>python -m http.server 8080 --cgi

という “--cgi” オプションを付けて実行します。このとき cgi-bin というフォルダを作成し、その中にpython で作成したCGIを格納する必要があります。

例えば、

helloworld_jp.py
print ("Content-Type: text/html\n");
print ("こんにちは 日本語!");

と記載してcgi-binフォルダに保存してみます。

ブラウザで確認

http://localhost:8080/cgi-bin/helloworld_jp.py にアクセスすると…

hello_japanese.png

と表示されます。

日本語でエラー発生

python3で作成したCGIをSJISコード(ANSI)で保存していた場合、文字コードによる以下のようなエラーが起動したコマンドプロンプトで発生します。ブラウザは真白で何も表示されないので必ずUTF-8で保存してください。

127.0.0.1 - - [xx/xx/xx xx:xx:xx] command: C:\Anaconda3\python.exe -u C:\python_http_server\cgi-bin\helloworld_jp_sjis.py ""
127.0.0.1 - - [xx/xx/xx xx:xx:xx] b'  File "C:\\python_http_server\\cgi-bin\\helloworld_jp_sjis.py", line 2\r\nSyntaxError: Non-UTF-8 code starting with \'\\x82\' in file C:\\python_http_server\\cgi-bin\\helloworld_jp_sjis.py on line 2, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details\r\n'
127.0.0.1 - - [xx/xx/xx xx:xx:xx] CGI script exit status 0x1

日本語でおかしなことがあったらここをチェック!
https://qiita.com/goodboy_max/items/a35fd133141543f26845

POST/GETでデータの引き渡し

POST/GETが簡単に実行できるようにHTMLファイルを作成します。
保存する文字コードはくれぐれも注意するように!

post_get_test.html
<html>
<head>
<title>テストフォーム</title>
<meta http-equiv="content-type" charset="utf-8">
</head>
<body>
■POST
<form action="http://localhost:8080/cgi-bin/post_get_test.py" method="post">
  <div>
    <label for="name">名前</label>
    <input name="name" id="name" value="POST 名前">
  </div>
  <div>
    <label for="addr">住所</label>
    <input name="addr" id="addr" value="POST 住所">
  </div>
  <div>
    <button>POST実行</button>
  </div>
</form>
<hr>
■GET
<form action="http://localhost:8080/cgi-bin/post_get_test.py" method="get">
  <div>
    <label for="name">名前</label>
    <input name="name" id="name" value="GET 名前">
  </div>
  <div>
    <label for="addr">住所</label>
    <input name="addr" id="addr" value="GET 住所">
  </div>
  <div>
    <button>GET実行</button>
  </div>
</form>

参考<br>
https://docs.python.jp/3/library/cgi.html

</body>
</html>

実行するCGIのpythonファイルを作成し、cgi-bin 以下に配置します。
python の cgiモジュールは変数取得のためにGET/POSTメソッドによって
処理を変更する必要はないのでメチャ楽だ!

post_get_test.py
import cgi
import os

# デバッグ用
import cgitb
cgitb.enable()

print ("Content-Type: text/html")
print()

print ("<html><body>")

form = cgi.FieldStorage()
form_check = 0

# formでの変数有無チェック
if "name" not in form or "addr" not in form:
  form_check = 1

print ("<h1>{0}変数出力</h1>".format(os.environ['REQUEST_METHOD']))

# パラメータエラー時の対応 
# python の cgiモジュールは変数取得のためにGET/POSTメソッドによって
# 処理を変更する必要はないのでメチャ楽だ!
if form_check == 1 :
  print ("<h2>ERROR !</h2>")
  print ("Please fill in the name and addr fields.")
else :
  print ("<b>名前: </b>", form["name"].value)
  print ("<b>住所: </b>", form["addr"].value)

print ("</body></html>")

http://localhost:8080/post_get_test.html にアクセスしてみます。

post_get_test_html.png

POST実行してみます。

post_test_cgi.png

GET実行してみます。

get_test_cgi.png

以上です。

goodboy_max
千葉在住Maximilian 2015.4.27生まれ。 ジャパンカップ 2017 にて125mを9.258秒(予選は100m7.4秒)で走り日本一早いサイトハウンド大型犬になりました。😎😎😎 海と犬が大好き!お仕事の気分転換に書いていきますのでよろしくお願いします。
https://www.instagram.com/max_gogo_kun
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした