0

GB2312 でエンコードされた RSS フィードがあります

次のコードを使用して解析しようとすると:

for item in XML.ElementFromURL(feed).xpath('//item'):
    title = item.find('title').text

フィードを解析できません。

GB2312 でエンコードされた RSS フィードを解析する方法

以下のようにエンコードを使用した後、Plex Media Server からのエラー ログは以下のとおりです。

for item in XML.ElementFromURL(feed, encoding='gb2312').xpath('//item'):
        title = item.find('title').text

:

***Error Log:***
>  File "C:\Documents and Settings\subhendu.swain\Local Settings\Application Data\Plex Media Server\Plug-ins\Zaobao.bundle\Contents\Code\__init__.py", line 24, in GetDetails
    for item in XML.ElementFromURL(feed, encoding='gb2312').xpath('//item'):
  File "C:\Documents and Settings\subhendu.swain\Local Settings\Application Data\Plex Media Server\Plug-ins\Framework.bundle\Contents\Resources\Versions\2\Python\Framework\api\parsekit.py", line 81, in ElementFromURL
    return self.ElementFromString(self._core.networking.http_request(url, values, headers, cacheTime, autoUpdate, encoding, errors, immediate=True, sleep=sleep, opener=self._opener, txn_id=self._txn_id).content, isHTML=isHTML)
  File "C:\Documents and Settings\subhendu.swain\Local Settings\Application Data\Plex Media Server\Plug-ins\Framework.bundle\Contents\Resources\Versions\2\Python\Framework\api\parsekit.py", line 76, in ElementFromString
    return self._core.data.xml.from_string(string, isHTML)
  File "C:\Documents and Settings\subhendu.swain\Local Settings\Application Data\Plex Media Server\Plug-ins\Framework.bundle\Contents\Resources\Versions\2\Python\Framework\components\data.py", line 134, in from_string
    return etree.fromstring(markup)
  File "lxml.etree.pyx", line 2532, in lxml.etree.fromstring (src/lxml/lxml.etree.c:48270)
  File "parser.pxi", line 1545, in lxml.etree._parseMemoryDocument (src/lxml/lxml.etree.c:71812)
  File "parser.pxi", line 1424, in lxml.etree._parseDoc (src/lxml/lxml.etree.c:70673)
  File "parser.pxi", line 938, in lxml.etree._BaseParser._parseDoc (src/lxml/lxml.etree.c:67442)
  File "parser.pxi", line 539, in lxml.etree._ParserContext._handleParseResultDoc (src/lxml/lxml.etree.c:63824)
  File "parser.pxi", line 625, in lxml.etree._handleParseResult (src/lxml/lxml.etree.c:64745)
  File "parser.pxi", line 565, in lxml.etree._raiseParseError (src/lxml/lxml.etree.c:64088)
XMLSyntaxError: switching encoding: encoder error, line 1, column 36

2011-09-28 09:34:33,453 (9d0) :  DEBUG (core) - Response: 404
4

2 に答える 2

2

エラー メッセージはXMLSyntaxError: switching encoding: encoder error, line 1, column 36です。あなたはアイデアを求めました。ここに斬新なアイデアがあります。「1 行目」の最初の 50 バイトほどの内容を教えてください。そうすれば、誰かが救済策を思いつくかもしれません。

更新: エンコーディング宣言が正しくありません。データは でエンコードされていませんgb2312。それは少なくともGBK別名cp936です。GB2312-80 (1980 年では 80) は限定された文字セットです。UTF-8 を使用していない中国の Web サイトは、少なくともスーパーセット GBK (10 年以上使用されている) を使用し、スーパースーパーセット GB18030 (それ自体が UTF) に移行します。下記参照:

[Python 2.7.1]
>>> import urllib
>>> url = "http://www.zaobao.com/sp/sp.xml"
>>> data = urllib.urlopen(url).read()
>>> len(data)
10071
>>> data[:100]
'<?xml version="1.0" encoding="GB2312"?>\n\n<rss version="2.0"\n>\n\n<channel>\n<title>\xc1\xaa\xba\xcf\xd4\xe7\xb1\xa8\xcd\xf8 zaobao.co'
>>> x = data.decode('gb2312')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'gb2312' codec can't decode bytes in position 1771-1772: illegal multibyte sequence
>>> data[1771:1773]
'\x95N'
>>> x = data.decode('utf8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\python27\lib\encodings\utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xc1 in position 80: invalid start byte
>>> x = data.decode('gbk')
>>> y = data.decode('cp936')
>>> x == y
True

試してみることをお勧めしますXML.ElementFromURL(feed, encoding='gbk')

それが機能する場合は、urllib を使用してデータを読み取り、チェックしgb2312、見つかった場合はgb18030代わりに使用することにより、この珍しくない問題に対してコードを完全に保護することをお勧めします。

更新 2: 誰かが言及した場合chardet: GBK が GB2312 の多くの未使用スロットを使用し、chardet が実際に使用されているスロットで動作せず、試用デコードを行ってその答えを検証しようとしないため、charget は GB2312 を推測します。

于 2011-09-28T11:58:05.957 に答える
1

PlexXMLAPIを使用していると思います。XML.ElementFromURL(feed, encoding='gb2312')ドキュメントには、これが実際に使用されているエンコーディングであることがわかっている場合は、呼び出すことができると記載されています。

XMLが実際にGB2312でエンコードされている場合、宣言は<?xml version="1.0" encoding="gb2312"?>(または、UTF-16の場合はバイト順マークで始まる)でなければなりません。そうでない場合、XMLは無効です。XML宣言にがなくencoding、バイト順マークがない場合、パーサーはデフォルトでUTF-8エンコードを想定する必要があるため、宣言にがないXMLに他の文字エンコードを使用することは無効encodingです。エンコーディングを指定しないとエラーが発生するため、RSSフィードが有効なXMLではない可能性があると思います。

于 2011-09-27T13:54:30.130 に答える