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

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

新規登録して質問してみよう
ただいま回答率
85.48%
CGI

CGI(Common Gateway Interface)とは、Webサーバー上でユーザプログラム動作させる仕組みのこと。また、動かす前提のプログラムをCGIと呼ぶこともあります。HTMLなどの静的な情報に限らず、プログラムの処理結果をベースにした動的情報の提供が可能です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

3350閲覧

htmlのフォームから読み込んだファイルを表示させると文字化けしてしまう

tonk

総合スコア22

CGI

CGI(Common Gateway Interface)とは、Webサーバー上でユーザプログラム動作させる仕組みのこと。また、動かす前提のプログラムをCGIと呼ぶこともあります。HTMLなどの静的な情報に限らず、プログラムの処理結果をベースにした動的情報の提供が可能です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2019/12/05 21:26

編集2019/12/06 00:57

いつもお世話になります。
ひとつご教示ください。

やりたいこと

htmlのフォームからcgiでテキストファイルを読み込んで、内容を表示させたい。
https://www.gesource.jp/programming/python/cgi/0114.html
こちらのサイトの内容を参考に学習しています。
python2で書かれているため、ところどころ書き換えながら試しています。
環境は
python3.7
windows10
です。

わからないこと

内容の表示まではいくのですが、文字化けします。
自分ではこのあたりを試してみたのですが解消しません。
https://qiita.com/eleven-junichi2/items/f3fcb6abe7fe21a4d89a
http://wannaknowenglish.hatenablog.com/entry/2016/03/22/112223
他にも
https://teratail.com/questions/127384
等、teratail内の質問も見てみたのですが、同様のケースが見当たりませんでした。

あまりにも初心者すぎる質問かもしれませんが、もはや何を試せばよいのか分からなくなりました。
おそらくいろいろと見当違いなことをしてるのだと思いますが・・・
教えていただきたいと存じます。何卒よろしくお願いいたします。

追記

テキストファイルの文字コードはUTF-8として保存しています。
また投稿後にmetaタグを<meta charset="utf-8">に差し替えたところ、次はページ自体が文字化けしてしまいました。

python3

1#!/usr/bin/python3 2# -*- coding: utf-8 -*- 3 4html = """Content-Type: text/html 5 6<html> 7<head> 8<meta http-equiv="Content-Type" content="text/html" /> 9<title>選択されたファイルの内容を取得する</title> 10 <style type="text/css"> 11 <!-- 12 pre { 13 border-width: 1px; 14 border-style: dotted; 15 border-color: #009999; 16 margin: 1em; 17 padding: 1em; 18 } 19 --> 20 </style> 21</head> 22<body> 23<h1>選択されたファイルの内容を取得する</h1> 24<p>選択されたファイルの内容は 25<pre>%s</pre> 26です。</p> 27<form action="test14.py" method="post" enctype="multipart/form-data"> 28 <input type="file" name="filename" /> 29 <input type="submit" /> 30</form> 31</body> 32</html> 33""" 34 35import cgi 36import cgitb 37cgitb.enable() 38 39form = cgi.FieldStorage() 40data = "" 41if "filename" in form : 42 item = form["filename"] 43 if item.file: 44 data = item.file.read() 45print(html % data) 46 47# 出力するとこんな表示になってしまいます。 48# b'\xe3\x82\xa4\xe3\x83\xb3\xe3\x83\x95\xe3\x83\xab\xe3\x82\xa8\xe3\x83\xb3\xe3\x82\xb6\xe3\x81\xab\xe3\x81\x94\xe6\xb3\xa8\xe6\x84\x8f\xe3\x81\x8f\xe3\x81\xa0\xe3\x81\x95\xe3\x81\x84' 49

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/12/05 22:02 編集

応答ヘッダや meta タグで指定する文字コードとテキストファイルが使っている文字コードはどうなっていますか? (前者が utf-8 で後者が日本語混じりの Shift_JIS と言ったような不整合はありませんか?)
tonk

2019/12/05 23:46

ありがとうございます。 読み込むテキストファイルはUTF-8で指定してあります。 metaタグを上記コード8行目から<meta charset="utf-8">に差し替えてみたところ、 今度はページ自体が文字化けを起こしました。
退会済みユーザー

退会済みユーザー

2019/12/05 23:54

「テキストファイルはUTF-8で指定」とはどういう意味ですか? ファイルの中身のバイト列はどうなっているのでしょう?
tonk

2019/12/06 00:13

テキストファイルの文字コードをUTF-8として保存しています。 バイト列、というと内容のことでしたでしょうか。 適当な日本語の文字列のみとなっています。お答えになってますでしょうか。
退会済みユーザー

退会済みユーザー

2019/12/06 00:52

「テキストファイルの文字コードをUTF-8として保存しています。」を質問欄を編集して追記願います。ここコメント欄は初期表示の時は閉じていますので見ない人がいますから。
guest

回答2

0

ベストアンサー

python3 cgiモジュールのリファレンスを以下から参照すると、
cgi モジュールを使う - Python3.8

file 属性から以下のようにデータを読み込むことができます (read() および readline() メソッドはバイト列を返します):

とあります。つまり、CGIでフォームから送られたファイルを読み出した時のデータはUTF-8のバイト列なので、デコードしてあげなければなりません。具体的にはバイト列データ.decode(encoding='utf-8')でデコードできます。これを踏まえてご提示のコードを修正すると、以下のようになります。

Python3

1import cgi 2import cgitb 3cgitb.enable() 4 5form = cgi.FieldStorage() 6 7# バイト列として扱う (data=""では文字列型になってしまうので、ダメ) 8data = b"" 9if "filename" in form : 10 item = form["filename"] 11 if item.file: 12 # fileからバイト列として読み出し 13 data = item.file.read() 14 15#print(html % data) 16# UTF-8のバイト列を文字列に変換 17s = data.decode(encoding='utf-8') 18print(html % s)

Unicode HOWTO - Python3.8

投稿2019/12/06 04:33

dodox86

総合スコア9183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tonk

2019/12/07 22:43

ご回答ありがとうございました。 見事変換されました。read()メソッドでファイルで読み込んだ時点ではいわゆるバイナリーデータのため、テキストとして表示するには文字列に変換しなければならなかったという理解で良かったでしょうか?
dodox86

2019/12/08 02:29

> read()メソッドでファイルで読み込んだ時点ではいわゆるバイナリーデータのため、テキストとして表示するには文字列に変換しなければならなかったと そのご理解でよろしいかと思います。補足として正確に言うと、read()メソッドで読み出したデータは組み込み型のbytes(クラス)で、 (pythonの対話モードでの実行例) >>> s = b"1234" >>> print(type(s)) <class 'bytes'> 文字列は組み込み型のstr(クラス)であるため、変換する必要があると言うことです。 >>> s = "1234" >>> print(type(s)) <class 'str'> >>>
tonk

2019/12/09 21:17

今回のことは、データの型でつまづいていたということですね。 受け渡しの仕方について、より意識するようにします。 どうもありがとうございました。
guest

0

テキストファイルの文字コードをUTF-8として保存しています。

そのようですね。質問に書いてあった結果の文字列、

\xe3\x82\xa4\xe3\x83\xb3 ... \xe3\x81\x84

は UTF-8 のバイト列、

e3 82 a4 e3 83 b3 ... e3 81 84

を表しているようで、それを復号すると「インフルエンザにご注意ください」となります。それで間違いないですよね。

それで間違いなければ、ファイルのバイト列のエンコーディング・デコーディングができておらず、バイト列がそのまま出てきたということのようです。

ただ、お役に立てずすみませんが、自分は Python は門外漢なので、どこが問題なのかは分かりません。デバッグ実行できるのであれば data に何が取得できているか調べるとヒントが見つかるかもしれません。

投稿2019/12/06 01:03

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tonk

2019/12/07 22:47

ご回答ありがとうございました。 処理を行う都度、データの取り扱い方も合わせて考えなければならないといつも思っているのですが、バイト列のエンコードだったとは、私の知らない知識でした。 適切な回答が得られたのも、最初から導いていただけたからと思っております。 どうもありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問