美丽的汤和Unicode问题

Jon*_*sco 8 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属性中看到了这一点:

<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;" />
Run Code Online (Sandbox Code Playgroud)

当BeautifulSoup解析它时,我看到:

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

如果我尝试将其编码为UTF-8,就像这样评论建议: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."'
Run Code Online (Sandbox Code Playgroud)

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

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

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

3-当我编码为UTF8时,哪里确实\xa0成为了\xc2\xa0

我可以通过一切unicodedata.normalize('NFKD',string)来帮助我找到我想去的地方 - 但我很想知道什么是错的,并避免将来出现这样的问题.

Bri*_*ell 24

你没有遇到问题.一切都按照预期行事.

&nbsp;表示不间断的空格字符.这不会被空格所取代,因为它不代表空间; 它代表了一个不间断的空间.用空格替换它会丢失信息:在该空间发生的地方,文本呈现引擎不应该放置换行符.

非中断空间的Unicode代码点是U + 00A0,它在Python中用Unicode字符串写成\xa0.

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

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

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