1

当我运行 eclipse 或在 iPython 中运行我的脚本时,它失败了:

'ascii' codec can't decode byte 0xe2 in position 32: ordinal not in range(128) 

我不知道为什么,但是当我使用相同的 url 简单地执行 feedparse.parse(url) 语句时,没有抛出错误。这让我很难过。

代码很简单:

      try:
           d = feedparser.parse(url)
      except Exception, e:
           logging.error('Error while retrieving feed.')
           logging.error(e)
           logging.error(formatExceptionInfo(None))
           logging.error(formatExceptionInfo1())

这是堆栈跟踪:

d = feedparser.parse(url)


 File "C:\Python26\lib\site-packages\feedparser.py", line 2623, in parse
    feedparser.feed(data)
  File "C:\Python26\lib\site-packages\feedparser.py", line 1441, in feed
    sgmllib.SGMLParser.feed(self, data)
  File "C:\Python26\lib\sgmllib.py", line 104, in feed
    self.goahead(0)
  File "C:\Python26\lib\sgmllib.py", line 143, in goahead
    k = self.parse_endtag(i)
  File "C:\Python26\lib\sgmllib.py", line 320, in parse_endtag
    self.finish_endtag(tag)
  File "C:\Python26\lib\sgmllib.py", line 360, in finish_endtag
    self.unknown_endtag(tag)
  File "C:\Python26\lib\site-packages\feedparser.py", line 476, in unknown_endtag
    method()
  File "C:\Python26\lib\site-packages\feedparser.py", line 1318, in _end_content
    value = self.popContent('content')
  File "C:\Python26\lib\site-packages\feedparser.py", line 700, in popContent
    value = self.pop(tag)
  File "C:\Python26\lib\site-packages\feedparser.py", line 641, in pop
    output = _resolveRelativeURIs(output, self.baseuri, self.encoding)
  File "C:\Python26\lib\site-packages\feedparser.py", line 1594, in _resolveRelativeURIs
    p.feed(htmlSource)
  File "C:\Python26\lib\site-packages\feedparser.py", line 1441, in feed
    sgmllib.SGMLParser.feed(self, data)
  File "C:\Python26\lib\sgmllib.py", line 104, in feed
    self.goahead(0)
  File "C:\Python26\lib\sgmllib.py", line 138, in goahead
    k = self.parse_starttag(i)
  File "C:\Python26\lib\sgmllib.py", line 296, in parse_starttag
    self.finish_starttag(tag, attrs)
  File "C:\Python26\lib\sgmllib.py", line 338, in finish_starttag
    self.unknown_starttag(tag, attrs)
  File "C:\Python26\lib\site-packages\feedparser.py", line 1588, in unknown_starttag
    attrs = [(key, ((tag, key) in self.relative_uris) and self.resolveURI(value) or value) for key, value in attrs]
  File "C:\Python26\lib\site-packages\feedparser.py", line 1584, in resolveURI
    return _urljoin(self.baseuri, uri)
  File "C:\Python26\lib\site-packages\feedparser.py", line 286, in _urljoin
    return urlparse.urljoin(base, uri)
  File "C:\Python26\lib\urlparse.py", line 215, in urljoin
    params, query, fragment))
  File "C:\Python26\lib\urlparse.py", line 184, in urlunparse
    return urlunsplit((scheme, netloc, url, query, fragment))
  File "C:\Python26\lib\urlparse.py", line 192, in urlunsplit
    url = scheme + ':' + url
  File "C:\Python26\lib\encodings\cp1252.py", line 15, in decode
    return codecs.charmap_decode(input,errors,decoding_table)

部分解决:

当传递给 feedparser.parse() 的 URL 是 unicode 时,这是可重现的。当它是一个 ascii URL 时,它不会重现。作为记录,您需要一个包含一些高字符 unicode 字符的提要。我不确定这是为什么。

4

2 回答 2

1

看起来给您带来问题的 url 包含具有某种编码的文本(例如 latin-1,其中0xe2将是“小写 a,顶部有一个圆圈”aka â)没有正确的内容类型标题(它应该有一个 charset= 参数在Content-Type:但没有)。

如果是这种情况feedparser,无法猜测编码,则尝试使用默认值 ( ascii),但失败。

feedparser 文档的这一部分更详细地解释了这些问题。

不幸的是,没有“灵丹妙药”来解决这个普遍问题(由于 bozos 违反了 XML 规则)。您可以尝试捕获此异常,并在处理程序中分别读取 url 的内容(使用urllib2)并尝试使用各种可能的编码对其进行解码 - 然后当您最终以这种方式获得可用的 unicode 对象时,将提供给feedparser.parse(其第一个 arg 可以是url、文件流带有数据的 unicode 字符串)。

于 2010-05-18T14:16:00.760 回答
1

参考 OP 的评论:尝试任何 url 文字,例如 u'myfeed.blah/xml' 它应该重现。

>>> from pprint import pprint as pp
>>> import feedparser

>>> d = feedparser.parse(u'myfeed.blah/xml')
>>> pp(d)
{'bozo': 1,
 'bozo_exception': SAXParseException('not well-formed (invalid token)',),
 'encoding': 'utf-8',
 'entries': [],
 'feed': {},
 'namespaces': {},
 'version': ''}

>>> d = feedparser.parse(u'http://myfeed.blah/xml')
>>> pp(d)
{'bozo': 1,
 'bozo_exception': URLError(gaierror(11001, 'getaddrinfo failed'),),
 'encoding': 'utf-8',
 'entries': [],
 'feed': {},
 'version': None}

>>> d = feedparser.parse("http://feedparser.org/docs/examples/atom10.xml")
>>> d['bozo']
0
>>> d['feed']['title']
u'Sample Feed'

>>> d = feedparser.parse(u"http://feedparser.org/docs/examples/atom10.xml")
>>> d['bozo']
0
>>> d['feed']['title']
u'Sample Feed'
>>>

请停止折腾;提供一个实际导致问题的 URL。

于 2010-05-19T21:43:58.853 回答