3

Webページを取得したら、次のようにUnicodeDammitを使用してutf-8エンコーディングに変換します。

import chardet
from lxml import html
content = urllib2.urlopen(url).read()
encoding = chardet.detect(content)['encoding']
if encoding != 'utf-8':
    content = content.decode(encoding, 'replace').encode('utf-8')
doc = html.fromstring(content, base_url=url)

しかし、私が使用するとき:

text = doc.text_content()
print type(text)

出力は<type 'lxml.etree._ElementUnicodeResult'>です。なぜ?utf-8文字列になると思いました。

4

2 に答える 2

7

lxml.etree._ElementUnicodeResultから継承するクラスですunicode:

$ pydoc lxml.etree._ElementUnicodeResult

lxml.etree._ElementUnicodeResult = class _ElementUnicodeResult(__builtin__.unicode)
 |  Method resolution order:
 |      _ElementUnicodeResult
 |      __builtin__.unicode
 |      __builtin__.basestring
 |      __builtin__.object

Python では、基本型から拡張してモジュール固有の機能を追加するクラスを持つことはかなり一般的です。通常の Unicode 文字列のようにオブジェクトを安全に扱う必要があります。

于 2012-12-21T03:31:46.550 に答える
1

はソース ファイルで指定されたエンコーディングを自動的に使用するため、再エンコーディングの手順をスキップしたいlxml.html場合があります。最終的に有効な Unicode になる限り、最初にどのようにエンコードされたかを気にする必要はおそらくありません。

あなたのプロジェクトが非常に小さく非公式で、8 ビットの文字列 (つまり、特殊文字を含まない常に 7 ビットの ASCII、英語) に遭遇することがないと確信できる場合を除き、できるだけ早くテキストを Unicode に変換することが賢明です (取得直後など)、ファイルへの書き込みまたはソケット経由での送信のためにシリアル化する必要があるまで、そのままにしておきます。

あなたが見て<type 'lxml.etree._ElementUnicodeResult'>いる理由lxml.html.fromstring()は、 が自動的にデコード ステップを実行しているためです。これは、上記のコードが UTF-16 でエンコードされたページでは機能しないことを意味することに注意してください。たとえば、8 ビット文字列は UTF-8 でエンコードされますが、html は依然として utf-16 を示しているためです。

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

lxml は utf-16 エンコーディング規則に基づいて文字列をデコードしようとし、すぐに例外を発生させます。

出力をUTF-8でエンコードされた 8 ビット文字列としてシリアル化する場合、必要なのは次のとおりです。

>>> text = doc.text_content().encode('utf-8')
>>> print type(text)
<type 'str'>
于 2013-02-18T01:04:48.687 に答える