2012-01-06 11 views
16

urllib2.urlopenを使ってWebページを読み込んで、さまざまな魔法を実行し、printを使って結果を吐き出すPythonスクリプトを持っています。私たちは、そのようにのようにWindows上でプログラムを実行します。Peter PiperはPythonプログラムをパイプして、すべてのユニコード文字を失った

python program.py > output.htm 

ここで問題です:

urlopenはUTF8を出力IIS Webサーバーからデータを読み出します。これは同じデータを出力に吐き出しますが、特定の文字(Wordが常にあなたよりもスマートなのであなたの意志にあなたのために挿入する長いハイフンなど)は、文字化けして–のようになります。

さらに調査したところ、WebサーバーがUTF8データを吐き出したとしても、output.htmファイルはISO-8859-1文字セットでエンコードされていました。

私の質問:

  1. は、Windows上の出力ファイルにPythonプログラムをリダイレクトするとき、それは常に、この文字セットを使用していますか?
  2. もしそうなら、その動作を変更する方法はありますか?
  3. そうでない場合は、回避策がありますか?私はちょうどコマンドラインのパラメータとしてoutput.htmを渡すことができ、画面の代わりにそのファイルに書き込むことができると思うが、私のプログラムでは一揃いのロジックをやり直す必要があるだろう。

ありがとうございました!

UPDATE:output.htmの上部に

私が追加:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> 

をしかし、それは違いはありません。文字はまだ文字化けしています。 Firefoxで手動でUTF-8に切り替えると、ファイルが正しく表示されます。 IEとFFの両方とも、明らかにそうではないが、このファイルは西洋のISOだと思う。

+1

パイプではありません。それはリダイレクトです。エンコーディングをしているのは 'print'です。パイプやリダイレクトはWindowsのPythonの外で処理されます。 –

+0

あなたが言うように "文字化け"に終わった場合、出力*は* UTF-8です。ファイルを表示しているものはISO-8859-1と解釈しています。つまり、結果のHTMLファイルには、エンコーディングを示すXMLプロローグ、またはContent-Typeを指定するメタタグがありますか? – slyfox

+3

これはあまり変わりがありません。 –

答えて

8

あなたのコメントと質問の更新から、データがUTF-8で正しくエンコードされているようです。

<head> 
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 
</head> 

場合は、実際にXML宣言を使用しないでください。これは、あなたがちょうどそれがどちらか、UTF-8ですBOM、またはより良いを使用することによって、あなたのHTML文書にエンコーディング情報を追加することで、ブラウザに指示する必要があることを意味しますドキュメントは有効なXMLではありません。

最も信頼性の高い方法は、HTTP経由でファイルを提供し、Content-Type:ヘッダーを適切に設定することです。

+0

それは、ありがとう!だから、私はWindows上でPythonスクリプトをリダイレクトするときに、PythonがUTF8バイトを吐き出しているにもかかわらず、デフォルトのWindowsコードページ(Western ISO)を使用していると推測しています。したがって、ファイルにはUTF8バイトの西洋ISO BOMがあります。 IEまたはFFでファイルを読み込むと、BOMが表示され、 'meta'タグがそれをオーバーロードしないので、BOMを使用します。私がIISでファイルを提供する場合、IISはおそらくこれも検出し、 'content-type'ヘッダーをWestern ISOに設定します。私はメタタグを使うのがこの状況での最良の解決だと思うので、あなたの答えは '+ 1'です。 –

+0

@Mike: 'latin1' /' ISO-8859-1'はASCIIの拡張であり、BOMはありません。あなたのスクリプトは完璧に動作し、リダイレクトも大丈夫です。何が問題になったのは、あなたのドキュメントに* UTF-8 BOMがないか、またはWebサーバーが全くエンコーディングを指定しておらず、ブラウザがデフォルトのエンコーディングを使用しただけなので、あなたのWebサーバーが間違った 'Content-Type'それはそれ以上は言わなかった。ところで、これはWindows固有の問題ではなく、同様の方法でLinux上で間違っている可能性があります。 –

+0

ああ、ファイルにはBOMがまったくないと思います。 Pythonは恐らく画面にBOMを出力するだけではないでしょうし、Windowsはおそらく '>' –

5

Windowsの出力ファイルにPythonプログラムをパイプすると、常にこの文字セットが使用されますか?

パイプへの出力に使用されるデフォルトのエンコーディング。私のマシンでは:

In [5]: sys.getdefaultencoding() 
Out[5]: 'ascii' 

ない場合、回避策はありますか?これで、すべての出力が 'UTF-8' に符号化されている

import sys 
try: 
    sys.setappdefaultencoding('utf-8') 
except: 
    sys = reload(sys) 
    sys.setdefaultencoding('utf-8') 

私は

せずにこのような状況を処理するための正しい方法は、論理

の全体の束がunicodeにサーバーやページのエンコードからあなたのインターネットのソースからすべてのデータをデコードすることでやり直し、と考える

上記の回避策を使用して、デフォルトのエンコードをutf-8に設定します。

2

Windows版のほとんどのプログラムは、デフォルトのWindowsエンコードを使用していると想定しています。英語のインストールでは、ISO-8859-1が使用されます。これはコマンドウィンドウの出力にも適用されます。 UTF-8にデフォルトのエンコーディングを設定する方法はありません。コードページが定義されていますが、うまくサポートされていません。

編集者の中には、ファイルの先頭にあるBOM文字を認識してUTF-8に切り替えるエディタもありますが、これは保証されていません。

HTMLを生成する場合は、適切なcharsetタグを含める必要があります。ブラウザは正しく解釈します。

関連する問題