web-dev-qa-db-ja.com

Unicodeへのurllib2の読み取り

任意の言語で作成できるサイトのコンテンツを保存する必要があります。また、コンテンツでUnicode文字列を検索できる必要があります。

私は次のようなものを試しました:

import urllib2

req = urllib2.urlopen('http://lenta.ru')
content = req.read()

コンテンツはバイトストリームなので、Unicode文字列を検索できます。

urlopenを実行してから、ヘッダーの文字セットを使用してコンテンツをデコードし、UTF-8にエンコードするために読み込むときに、何らかの方法が必要です。

46
Vitaly Babiy

実行した操作の後に、次が表示されます。

>>> req.headers['content-type']
'text/html; charset=windows-1251'

など:

>>> encoding=req.headers['content-type'].split('charset=')[-1]
>>> ucontent = unicode(content, encoding)

ucontentは、Unicode文字列(140655文字)になりました。たとえば、端末がUTF-8の場合、その一部を表示するには:

>>> print ucontent[76:110].encode('utf-8')
<title>Lenta.ru: Главное: </title>

検索などができます.

編集:通常、Unicode I/Oはトリッキーです(これが元の質問者を支えている可能性があります)が、Unicode文字列をインタラクティブなPythonインタープリターに入力するという難しい問題をバイパスします(完全に元の質問とは無関係)、Unicode文字列ISが正しく入力されたら(コードポイントでそれをやっています-愚かではありますがトリッキーではありません;-)より簡単に(したがって、元の質問が完全に回答されたことを願っています。)再びUTF-8端末を想定します。

>>> x=u'\u0413\u043b\u0430\u0432\u043d\u043e\u0435'
>>> print x.encode('utf-8')
Главное
>>> x in ucontent
True
>>> ucontent.find(x)
93

:一部のサイトは提供されるドキュメント内で文字エンコードのみを指定するため(たとえば、http-equivメタタグを使用)、この方法はすべてのサイトで機能しない場合があることに注意してください。

99
Alex Martelli

パースします Content-Type httpヘッダー、cgi.parse_header 関数:

import cgi
import urllib2

r = urllib2.urlopen('http://lenta.ru')
_, params = cgi.parse_header(r.headers.get('Content-Type', ''))
encoding = params.get('charset', 'utf-8')
unicode_text = r.read().decode(encoding)

文字セットを取得する別の方法:

>>> import urllib2
>>> r = urllib2.urlopen('http://lenta.ru')
>>> r.headers.getparam('charset')
'utf-8'

またはPython 3:

>>> import urllib.request
>>> r = urllib.request.urlopen('http://lenta.ru')
>>> r.headers.get_content_charset()
'utf-8'

文字エンコードは、HTMLドキュメント内で指定することもできます(例:<meta charset="utf-8">

10
jfs