質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.52%

【Python】htmlがweb上で表示されない。

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 4,326

fk_junya

score 5

参考書先々週に買い、プログラミングを始めたてのものです。
以下のプログラム(一行でのチャット)を動かしてみる過程で行き詰まりました。一日かけてもわからなかったので質問させていただきます。

Windows PowerShellで簡易サーバー(localhost:8080)を作った後、webで表示しようとしても画面が真っ白なままです。この時PowerShellには

CGI script exited OK


と表示されています。
python3.6、での稼働です。
どのようにすれば文字化けもなくきれいに表示できるのでしょうか。
回答よろしくお願いいたします。

#!/usr/bin/env python3

import cgi
import cgitb
import os.path
import html

#ブラウザーでのデバックを有効にする
cgitb.enable()

#全体の設定
FILE_LOG = "chat-log.txt"

#HTMLを画面に表示する
def print_html(body):
    #ヘッダーを出力
    print("Content-Type: text/html; charset=utf-8")
    print("")
    #HTMLを出力
    print ("""
    <html><head><meta charset="utf-8">
    <title>チャット</title></head><body>
    <h1>チャット</h1>
    <div><form>
    名前 : <input type="text" name="name" size ="8">
    本文 : <input type="text" name="body" size ="20">
    <input type="submit" value="発言">
    <input type="hidden" name="mode" value="write">
    </form></div><hr>
    {0}
    </body></html>
        """.format(body))

#チャットに書き込みログを表示する
def mode_read(form):
    #ログを読み取る
    log =""
    if os.path.exists(FILE_LOG):
        with open(FILE_LOG,"r",encoding="utf-8") as f:
            log = f.read()
        print_html(log)

#任意のURLにジャンプする
def jump(url):
    #ヘッダー出力
    print("status: 301 Moved permanently")
    print("Location:" + url)
    print("")
    #HTMLを出力(ヘッダーがうまくいかなかった時の対策)
    print('<html><head>')
    print('<meta http-equiv="refresh" content="0;'+url+'">')
    print('</head><body>')
    print('<a href="'+url+'">jump</a></body></html>')

#メッセージの書き込み
def mode_write(form):
    #パロメーターの取得
    name=form.getvalue("name","no name")
    body=form.getvalue("body","")
    #HTMLに変換
    name=html.escape(name)
    body=html.escape(body)
    #ファイルに保存
    with open(FILE_LOG, "a+", encoding='utf-8') as f:
        f.write("<p>{0}:{1}</p><hr>\n".format(name,body))
    #書き込み後にリダイレクト
    jump('chat.py')

#メイン処理
def main():
    #フォームの値を取得
    form=cgi.FieldStorage()
    #modeパラメータを取得
    mode=form.getvalue("mode","read")
    #modeの値によって処理を変更
    if mode =="read": mode_read(form)
    elif mode =="write": mode_write(form)
    else: mode_read(form)

if __name__=="__main__":
    main()
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

参考書の内容に関しては参考書の出版社に問い合わせをしたほうが良いと思いますが。

質問文のcgiスクリプトをデバック実行して確認した処
mode_read関数内で呼び出しているのprint_html関数のインデントが正しくありません。(1個深い)
print_htmlでHTMLデータを表示しているため、ログファイルが存在しない時にHTMLデータが表示されません。

Note:もしくはログファイルが存在するのが前提のソースコードなのかもしれません。
参考書にその旨記載してませんでしたか?

以下はインデントを修正後のソースコードです。

def mode_read(form):
    #ログを読み取る
    log =""
    if os.path.exists(FILE_LOG):
        with open(FILE_LOG,"r",encoding="utf-8") as f:
            log = f.read()
    print_html(log)


■実行フォルダ構成は以下の形になると思われます。

/
├─ cgi-bin  …フォルダなければ作成
│         └─chat.py …質問文のソースコードを設置
├─ chat-log.txt … チャットログ なければ作成
└─ この位置で コマンドプロンプトより py.exe -m http.server --cgi 8080 のコマンドを実行する。

アクセス先

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/07 10:16 編集

    ご回答ありがとうございます。
    インデントを改善したとこで画面に表示はできました。Pythonではインデントが重要なのを痛感いたしました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.52%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる