【问题标题】:Beautiful Soup and Unicode Problems美丽的汤和 Unicode 问题
【发布时间】:2013-10-30 18:24:22
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: python unicode beautifulsoup


    【解决方案1】:

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

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

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

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

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

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

    【讨论】:

    • 哇。非常感谢你,布赖恩。这是一个非常详细的回应。我不理解 2byte 序列,这解释了我 99% 的其他问题!顺便说一句 - 我很确定在这个例子中使用它的原因是“CMS Cruft”(我遇到过太多次了)。
    • 是的,“CMS Cruft”在尝试解析 HTML 时总是一个问题。
    猜你喜欢
    • 2011-08-07
    • 2016-05-19
    • 2023-03-27
    • 2021-03-20
    • 2010-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多