10

我正在使用 BeautifulSoup 来解析一些网页。

有时我会遇到如下“unicode hell”错误:

在 TheAtlantic.com 上查看本文的来源 [ http://www.theatlantic.com/education/archive/2013/10/why-are-hundreds-of-harvard-students-studying-ancient-chinese-philosophy/ 280356/ ]

我们在 og:description 元属性中看到了这一点:

<meta property="og:description" content="The professor who teaches&nbsp;Classical Chinese Ethical and Political Theory claims, &quot;This course will change your life.&quot;" />

当 BeautifulSoup 解析它时,我看到:

>>> print repr(description)
u'The professor who teaches\xa0Classical Chinese Ethical and Political Theory claims, "This course will change your life."'

如果我尝试将其编码为 UTF-8 ,就像这个 SO 评论建议的那样:https ://stackoverflow.com/a/10996267/442650

>>> print repr(description.encode('utf8'))
'The professor who teaches\xc2\xa0Classical Chinese Ethical and Political Theory claims, "This course will change your life."'

就在我以为我所有的 unicode 问题都得到控制的时候,我仍然不太明白发生了什么,所以我要提出几个问题:

1- 为什么 BeautifulSoup 会将 转换&nbsp;\xa0[拉丁字符集空格字符]?此页面上的字符集和标题是 UTF-8,我认为 BeautifulSoup 会提取该数据进行编码?为什么不替换为<space>?

2-有没有一种通用的方法来规范化空格以进行转换?

3-当我编码为 UTF8 时,\xa0序列在\xc2\xa0哪里?

我可以通过管道传递所有内容unicodedata.normalize('NFKD',string)以帮助我到达我想去的地方 - 但我很想了解哪里出了问题并避免将来出现此类问题。

4

1 回答 1

28

你没有遇到问题。一切都按预期运行。

&nbsp;表示一个不间断的空格字符。这没有用空格代替,因为它不代表空格;它代表一个不间断的空间。用空格替换它会丢失信息:在该空格出现的地方,文本渲染引擎不应该换行。

不间断空格的 Unicode 代码点是 U+00A0,它在 Python 中以 Unicode 字符串形式编写为\xa0.

U+00A0的UTF-8编码是十六进制的两个字节序列 C2 A0,或者写成 Python 字符串表示,\xc2\xa0. 在 UTF-8 中,任何超出 7 位 ASCII 集的内容都需要两个或更多字节来表示。在这种情况下,最高位设置为第八位。这意味着它可以由两字节序列(二进制)110xxxxx 10xxxxxx表示,其中 x 是代码点的二进制表示的位。在 A0 的情况下,即10000000UTF-811000010 10000000或 C2 A0 编码时。

许多人&nbsp;在 HTML 中使用来获取通常的 HTML 空白折叠规则不会折叠的空格(在 HTML 中,所有连续空格、制表符和换行符的运行都被解释为单个空格,除非应用了CSSwhite-space规则之一),但这并不是它们的真正用途;它们应该用于名称之类的东西,例如“Miyagi”,您不希望“Mr.”之间有换行符。和“宫城”。我不确定为什么在这种特殊情况下使用它;这里似乎不合适,但这更多是您的源代码的问题,而不是解释它的代码。

现在,如果您并不真正关心布局,因此您不介意文本布局算法是否选择它作为包装的地方,但只想将其解释为常规空间,那么使用 NFKD 进行规范化是完全合理的回答(或 NFKC,如果您更喜欢预先组合的口音而不是分解的口音)。NFKC和 NFKD 标准化映射字符,使得在大多数上下文中表示基本相同语义值的大多数字符被扩展。例如,连字扩展 (ffi -> ffi),古老的长 s 字符转换为 s (ſ -> s),罗马数字字符扩展为单独的字母 (IV -> IV),以及不间断空格转化为普通空间。对于某些字符,NFKC 或 NFKD 归一化可能会丢失在某些情况下很重要的信息:ℌ 和 ℍ 都将归一化为 H,但在数学文本中可用于指代不同的事物。

于 2013-10-22T03:41:14.170 回答