3

私はこれと1時間戦ってきました。XML文字列を。で解析していますiterparse。ただし、データが適切にエンコードされておらず、私はそのプロバイダーではないため、エンコードを修正できません。

これが私が得るエラーです:

lxml.etree.XMLSyntaxError: line 8167: Input is not proper UTF-8, indicate encoding !
Bytes: 0xEA 0x76 0x65 0x73

このエラーを単に無視して、解析を続行するにはどうすればよいですか?1つの文字が適切に保存されていなくても、データが必要なだけです。

これが私が試したもので、すべてインターネットから選んだものです。

data = data.encode('UTF-8','ignore')
data = unicode(data,errors='ignore')
data = unicode(data.strip(codecs.BOM_UTF8), 'utf-8', errors='ignore')

編集:
URLはプライベートAPIであり、APIキーが含まれているため、表示できませんが、これがデータの取得方法です。

ur = urlopen(url)
data = ur.read()

問題の原因となる文字は次のとおりです。、 &なども問題を解決åすると思います。äö

これが私がそれを解析しようとする部分です:

def fast_iter(context, func):
    for event, elem in context:
        func(elem)
        elem.clear()
        while elem.getprevious() is not None:
            del elem.getparent()[0]
    del context

def process_element(elem):
    print elem.xpath('title/text( )')

context = etree.iterparse(StringIO(data), tag='item')
fast_iter(context, process_element)

編集2:
これは、PHPで解析しようとするとどうなるかです。明確にするために、F***ingÅmålはドラマ映画=Dです

ファイルはで始まります<?xml version="1.0" encoding="UTF-8" ?>

これが私が得たものですprint repr(data[offset-10:offset+60])

ence des r\xeaves, La</title>\n\t\t<year>2006</year>\n\t\t<imdb>0354899</imdb>\n
4

5 に答える 5

3

あなたは言う:

問題の原因となる文字は次のとおりです。å、

どうやってわかったの?あなたはあなたのテキストを何で見ていますか?

そのため、URLとAPIキーを公開することはできません。データを読み取り、ファイルに書き込み(バイナリモードで)、それを公開するのはどうですか?

そのファイルをWebブラウザーで開くと、どのエンコードが検出されますか?

少なくとも、これを行う

data.decode('utf8') # where data is what you get from ur.read()

これにより、UTF-8以外のもののバイトオフセットを通知する例外が生成されます。

次に、これを行います。

print repr(data[offset-10:offset+60])

結果を表示します。

エンコーディングが実際にcp1252行われ、lxmlエラーメッセージのバイトをデコーディングしていると仮定します。

>>> guff = "\xEA\x76\x65\x73"
>>> from unicodedata import name
>>> [name(c) for c in guff.decode('1252')]
['LATIN SMALL LETTER E WITH CIRCUMFLEX', 'LATIN SMALL LETTER V', 'LATIN SMALL LE
TTER E', 'LATIN SMALL LETTER S']
>>>

それで、e-サーカムフレックスの後に、、vesまたはa-ringの後にves、またはa-ringの後に何か他のものが続くのを見ていますか?

データは次のようなXML宣言で始まります<?xml version="1.0" encoding="UTF-8"?>か?そうでない場合、それは何から始まりますか?

推測/確認をエンコードするための手がかり:テキストはどの言語で書かれていますか?どこの国?

提供された詳細情報に基づいて更新します。

エラーの近くに表示されたスニペットに基づいて、映画のタイトルは「La sciencedesrêves」(夢の科学)です。

PHPが「F***ingÅmål」をギャグするのはおかしいですが、Pythonはフランスの夢を窒息させます。同じクエリを実行してもよろしいですか?

事前にIMDBだと言っておくべきだったのに、もっと早く答えが返ってきたはずです。

解決策dataパーサーlxmlに渡す前に、次のようにします。

data = data.replace('encoding="UTF-8"', 'encoding="iso-8859-1"')

それは彼らが彼らのウェブサイトで宣言しているエンコーディングに基づいていますが、それも嘘かもしれません。その場合は、cp1252代わりに試してください。それは間違いなくiso-8859-2ではありません

于 2012-02-11T23:14:23.153 に答える
0

ただし、データが適切にエンコードされておらず、私はそのプロバイダーではないため、エンコードを修正できません。

なんとなくエンコードされています。エンコーディングを決定し、UTF-8エンコーディングの代わりにそのエンコーディングを指定します(明らかにエンコーディングではないため)。

于 2012-02-11T20:46:04.390 に答える
0

Iterparseを使用すると、keyword-argument "encoding"を使用してドキュメント内のxmlエンコーディングをオーバーライドできます(https://lxml.de/api/lxml.etree.iterparse-class.htmlを参照)。上記のコードでは、次のように書くこともできます

context = etree.iterparse(StringIO(data), tag='item', encoding='iso-8859-1') 

ファイル内のすべてのヨーロッパ文字を処理します。

于 2019-05-18T11:22:37.850 に答える
-1

解析中のエラーから回復するには、recoverオプションを使用できます(この場合、一部のデータは無視される可能性があります)。

import urllib2
from lxml import etree

data = urllib2.urlopen(URL).read()
root = etree.fromstring(data, parser=etree.XMLParser(recover=True))
for item in root.iter('item'):
    # process item here

ドキュメントのエンコーディングを上書きするには、次を使用できます。

parser=etree.XMLParser(encoding=ENCODING)

feedparser文字エンコードを検出する方法は次のとおりです(簡単ではありません)。

于 2012-02-12T11:13:13.417 に答える
-1

'replace'でencodeを使用できます- >>> unicode('\x80abc', errors='replace') このようにして、不正な文字が有効な文字に置き換えられます- u'\ufffdabc'

于 2012-02-11T18:51:20.050 に答える