2017-05-08 5 views
0
from urllib import urlopen 
web = urlopen("http://typographyforlawyers.com/straight-and-curly- 
quotes.html").read() 
web = web.replace("\xe2\x80\x9c".decode('utf8'), '"') 

"\ xe2 \ x80 \ x9c"は中かっこのUTF-8文字です。私はこのコードを使用してウェブサイトでのカーリー引用符を見つけるためにしようとすると、私はこのエラーを取得する:Python 2.7 - UTF-8文字の検索

Traceback (most recent call last): 
File "<pyshell#4>", line 1, in <module> 
web = web.replace("\xe2\x80\x9c".decode('utf8'), '"') 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 2265: 
ordinal not in range(128) 

このエラーは、何を意味する私が間違って何をやっている、と私はそれをどのように修正するのですか?

答えて

1

文字列をデコードするには、decode( 'utf-8')を使用する必要があります。

from urllib import urlopen 

web = urlopen("http://typographyforlawyers.com/straight-and-curly-quotes.html").read().decode('utf-8') 
web = web.replace(b"\xe2\x80\x9c".decode('utf8'), '"') 

print(web) 
+0

私はこの回答が好きですが、説明がより明示的になる可能性があります。 WebレスポンスをUnicodeに変換し、 'bytes'オブジェクトを使用してデコードするので、asciiコーデックに触れる理由はありません。また、HTML文書は ''タグと 'utf-8'のエンコーディングを頻繁に入れているのが正しいとは限りません。通常は正しくありますが、保証されません。 – tdelaney

+0

この回答をいただきありがとうございます。それは意味があります。 – Dman42

1

これは、文字列リテラルのデフォルトとして "ascii"コーデックを使用するPython 2インタープリターによるものです。将来のコード(Python 3)では、デフォルトはutf-8で、コードにUnicodeリテラル文字を含めることができます。将来のインポートを使用して、Python 2でこれを行うことができます。

from __future__ import unicode_literals 

from urllib import urlopen 

web = urlopen("http://typographyforlawyers.com/straight-and-curly-quotes.html").read() 
web = web.decode("utf-8") 
web = web.replace('“' , '"') 

print(repr(web)) 
+0

'unicode_literal'には潜在的な落とし穴がたくさんあります。 'web.decode(" utf-8 ")'が問題を修正しました。残りは危険です。 – tdelaney

+0

OPが実際に何を望んでいるのか分かりません。しかし、 'unicode_literal'に落とし穴があるかもしれませんが、あなたが正しく使用している場合はそうではありません。このような小さなスクリプトの場合、それはうまくいくでしょう。 – Keith

0

これはPython 2の解決策です。 Python 3は、文字列とバイトを別々に扱います。

私はあなたがwebにエンコードされた文字列を読んで、私はテストのためのシンプルなものを作っ

>>> web = "0123\xe2\x80\x9c789" 
>>> web.replace("\xe2\x80\x9c".decode('utf-8'), '"') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 4: ordinal not in range(128) 

で問題を再現することができます。検索文字列をデコードすると、ユニコードオブジェクトが作成されました。置換えを行うには、webをユニコードに変換する必要があります。

>>> "\xe2\x80\x9c".decode('utf-8') 
u'\u201c' 
>>> unicode(web) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 4: ordinal not in range(128) 

あなたが得たのはwebでした。 Python 2では、strはエンコードされたバイトを保持できます。 1つのオプションは、ページがUTF-8でエンコードされた知っていたので、単にエンコードされたバイトシーケンスに

>>> web.replace("\xe2\x80\x9c", '"') 
'0123"789' 

この作品だけを交換することです。それは通常の場合ですが、言及する価値があります。

関連する問題