lxml - 访问元素文本时的UnicodeDecodeError

时间:2013-01-15 08:08:28

标签: python html unicode utf-8 lxml

我正在使用一些Python代码,它使用lxml HTML解析器来解析同事从随机网站样本中删除的HTML。

在其中两个中,我收到了

形式的错误
  

“'utf8'编解码器无法解码位置502中的字节0xe20x80:意外   数据结束“,

并且HTML内容确实包含损坏的UTF-8字符。

名为ele的代码中的变量被分配给< p>带有坏字符的文本周围的元素,可以通过ele.text访问该文本。或者它可能是,但仅仅将ele.text分配给另一个变量会导致UnicodeDecodeError被引发。 except子句中可用的类型UnicodeDecodeError的对象包含一些有用的属性,例如文本中坏字节的开始和结束位置,可用于创建新字符串,坏字节具有该字符串已删除,但对ele.text执行任何操作(例如获取它的子字符串)会导致新的UnicodeDetectError被引发。我能做些什么来挽救ele.text的好部分吗?

我是从内存中写的,我不记得代码的所有细节,所以如果它有用,我明天可以提供更多信息。我记得ele是一个像lxml._Element类型的对象,被解析的文件确实在utf-8,文件中有一个前两个utf-8的位置与实体匹配的字符的字节数& rdquo;之后是实体& rdquo;。因此,该文本包含"xE2x80”"。错误消息抱怨"xE2x80",并在其中包含大约520个字符的字符串中给出它们的位置。如果有必要,我可以丢弃整个字符串,但我宁愿使用位置信息来丢弃"xE2x80"。出于某种原因,使用ele.text执行任何操作都会导致lxml中较低级别的Cython代码出错。我明天在工作时可以提供堆栈跟踪。如果我能用这个文字做什么的话怎么办?感谢。

1 个答案:

答案 0 :(得分:1)

e2 80个字节本身不会导致错误:

from lxml import html

html_data = b"<p>before &ldquo;\xe2\x80&rdquo; after"
p = html.fromstring(html_data)
print(repr(p.text))
# -> u'before \u201c\xe2\x80\u201d after'

正如@Esailija在评论中指出的,上述内容并未将数据解释为utf-8。强制使用utf-8编码:

from lxml import html

html_data = b"""<meta http-equiv="content-type"
                      content="text/html; charset=UTF-8">
                <p>before &ldquo;\xe2\x80&rdquo; after"""
doc = html.fromstring(html_data.decode('utf-8','ignore'))
print(repr(doc.find('.//p').text))
# -> u'before \u201c\u201d after'
  • 检查utf-8是文档的正确字符编码
  • 在将字节序列传递给lxml
  • 之前替换它