python - Beautiful Soup 和 Unicode 问题

标签 python unicode beautifulsoup

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

2- 是否有一种通用的方法来标准化转换中的空格?

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

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

最佳答案

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

  表示non-breaking space character .这不会被空格替换,因为它不代表空格;它代表一个不间断的空间。用空格替换它会丢失信息:在出现空格的地方,文本呈现引擎不应放置换行符。

不间断空格的Unicode编码点是U+00A0,在Python中用Unicode字符串写成\xa0

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

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

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

关于python - Beautiful Soup 和 Unicode 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19508442/

相关文章:

python - 导入错误: No module named bs4 because in wrong python folder

python - 为什么 BeautifulSoup 会抛出这个 HTMLParseError?

python - 如何查找具有特定值的文本 BeautifulSoup python2.7

python - Windows 中 OpenCV-Python 的自动完成功能不起作用

python - 我如何将python与bash中的py文件相关联

python - 类型对象 'RestrictionType' 没有属性 'size'

c++ - 使用 mbsnrtowcs 进行多字节到 Widechar 的转换

python - wsgi如何处理同名的多个请求头?

python - python中对非英文文件名的文件操作

android - 在 Android 中使用 iText 生成的 PDF 中不显示西里尔字母