nltk TweetTokenizer在输入字符串有效时导致UnicodeEncodeError,

xdnvmnnf  于 4个月前  发布在  其他
关注(0)|答案(2)|浏览(171)

结果将是:

UnicodeEncodeError: 'utf-8' codec can't encode character '\ud83d' in position 46: surrogates not allowed

输入字符串有效,但TweetTokenizer的输出出现了UnicodeEncodeError。这是不符合预期的。
测试环境:

  • Ubuntu Server 16.04
  • python 3.6
  • nltk 3.2.5
zbwhf8kr

zbwhf8kr1#

既然你使用的是Python3,nltk应该可以很好地处理字节中的utf8。

>>> from nltk.tokenize import TweetTokenizer
>>> text = "and i'm always happy when i saw his smile 😍😂�😍"
>>> ' '.join(tknz.tokenize(text))
"and i'm always happy when i saw his smile 😍 😂 \ud83d 😍"

但是在输出时,

>>> x = ' '.join(tknz.tokenize(text))
>>> x
"and i'm always happy when i saw his smile 😍 😂 \ud83d 😍"
>>> print(x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'utf-8' codec can't encode character '\ud83d' in position 46: surrogates not allowed

作为临时解决方案,你可以尝试用未知字符替换它,或者忽略并跳过这些字符,例如:

>>> print(x.encode('utf8', 'surrogatepass').decode('utf8', 'replace'))
and i'm always happy when i saw his smile 😍 😂 ��� 😍
>>> print(x.encode('utf8', 'surrogatepass').decode('utf8', 'ignore'))
and i'm always happy when i saw his smile 😍 😂  😍

但问题实际上出现在TweetTokenizer强制转换特殊HTML https://github.com/nltk/nltk/blob/develop/nltk/tokenize/casual.py#L295 时,并在 https://github.com/nltk/nltk/blob/develop/nltk/tokenize/casual.py#L202 处做出错误的假设。将其更改为 an invalid character

>>> from nltk.tokenize.casual import _replace_html_entities
>>> text = "and i'm always happy when i saw his smile 😍😂&#55357;😍"
>>> _replace_html_entities(text)
"and i'm always happy when i saw his smile 😍😂\ud83d😍"
>>> x = '&#55357;'
>>> _replace_html_entities(x)
'\ud83d'

此外,数据中存在 &#55357; 的事实意味着上游出了问题,你的数据在读取到可解析的HTML格式时被破坏了。
@hitvoice 这句话的来源是什么?
问题是,如果不强制执行 _replace_html_entities() ,TweetTokenizer 是否仍然有效?如果仍然有效,那么如果它能接受一个替换参数就更好了,例如 TweetTokenizer().tokenize(text, replace_html=True)

hgtggwj0

hgtggwj02#

感谢详细的解释!"replace_html"参数是个好主意。此外,我想知道是否可以自动忽略无法解析的HTML字符,而不是将其保留在输出列表中。TwitterTokenizer旨在处理非常脏的数据,这是合理的。
数据来自Twitter。我会尝试追踪损坏来源,但这并不容易。

相关问题