《Python Cookbook(第2版)中文版》——1.23 对Unicode数据编码并用于XML和HTML

简介:

本节书摘来自异步社区《Python Cookbook(第2版)中文版》一书中的第1章,第1.23节,作者[美]Alex Martelli , Anna Martelli Ravenscrof , David Ascher ,高铁军 译,更多章节内容可以访问云栖社区“异步社区”公众号查看。

1.23 对Unicode数据编码并用于XML和HTML

任务

你想对Unicode文本进行编码,使用一种有限制,但很流行的编码,如ASCII或Latin-1,并将处理后的结果用于HTML输出或者某些XML应用。

解决方案

Python提供了一种编码错误处理工具,叫做xmlcharrefreplace,它会将所有不属于所选编码的字符用XML的数字字符引用来替代:

def encode_for_xml(unicode_data, encoding='ascii'):
      return unicode_data.encode(encoding, 'xmlcharrefreplace')

也可以将此法用于HTML输出,不过你可能会更喜欢HTML的符号实体引用。出于这个目的,需要定义并注册一个自定义的编码错误处理函数。要实现这样一个处理函数非常简单,因为Python标准库已经提供了一个叫做htmlentitydefs的模块,包含了所有的HTML实体定义:

import codecs
from htmlentitydefs import codepoint2name
def html_replace(exc):
      if isinstance(exc, (UnicodeEncodeError, UnicodeTranslateError)):
             s = [ u'&%s;' % codepoint2name[ord(c)]
                       for c in exc.object[exc.start:exc.end] ]
             return ''.join(s), exc.end
      else:
             raise TypeError("can't handle %s" % exc._ _name_ _) 
codecs.register_error('html_replace', html_replace)

注册完错误处理函数之后,可以再写个包装函数,以简化使用:

def encode_for_html(unicode_data, encoding='ascii'):
      return unicode_data.encode(encoding, 'html_replace')

讨论

如同其他的一些Python模块一样,这个模块也将提供一个测试的示例,由if _name == ' main _'这一行语句进行保护:

if _ _name_ _ == '_ _main_ _':
      # demo
      data = u'''\
<html>
<head>
<title>Encoding Test</title>
</head>
<body>
<p>accented characters:
<ul>
<li>\xe0 (a + grave)
<li>\xe7 (c + cedilla)
<li>\xe9 (e + acute)
</ul>
<p>symbols:
<ul>
<li>\xa3 (British pound)
<li>\u20ac (Euro)
<li>\u221e (infinity)
</ul>
</body></html>
'''
      print encode_for_xml(data)
      print encode_for_html(data)

如果将此模块作为主脚本来运行,你会看到如下的输出(来自于encode_for_xml):

<li>&#224; (a + grave)
<li>&#231; (c + cedilla)
<li>&#233; (e + acute)
    ...
<li>&#163; (British pound)
<li>&#8364; (Euro)
<li>&#8734; (infinity)

还有这些(来自于encode_for_html):

<li>&agrave; (a + grave)
<li>&ccedil; (c + cedilla)
<li>&eacute; (e + acute)
    ...
<li>&pound; (British pound)
<li>&euro; (Euro)
<li>&infin; (infinity)

这两段输出都很清晰,不过encode_for_xml更加具有通用性(它可以用于任何XML应用,不仅仅是HTML),但encode_for_html却能够生成更易读的结果—如果希望直接读取或者编辑那些结果。如果给浏览器提供这两种形式的数据,能够看到渲染输出实际上是一样的。为了看到这两种方式在浏览器中的展示,可以将上述代码作为主脚本运行,将输出导向到一个磁盘文件,并用文本编辑器将这两种输出分隔开来,然后用浏览器分别查看。(再或者,运行脚本两次,一次将调用encode_for_xml的输出注释掉,一次将encode_for_html的输出注释掉)。

请记住,Unicode数据在被打印或者写到文件之前一定要先编码。由于UTF-8能够处理任何Unicode字符,所以它是理想的编码。但对很多用户和应用而言,ASCII或Latin-1比UTF-8更受欢迎。当Unicode数据包含了指定编码之外的字符时(比如,一些重音字符和很多符号大多不在ASCII或Latin-1之中,比如,Latin-1无法表现“无穷”符号),单靠这些编码本身,根本无法处理这些数据。Python提供一个内建的编码错误处理函数,叫做xmlcharrefreplace,将所有的不能被编码的字符替换为XML的数字字符引用,比如“∞”,表示“无穷”符号。本节还展示了怎样编写和注册另一个类似的错误处理函数html_replace,针对HTML输出进行处理。html_replace将不能编码的字符替换为更具可读性的HTML符号实体引用,比如用“∞”来表示“无穷”符号。html_replace相比于xmlcharrefreplace,它的通用性没那么好,因为它并不支持所有的Unicode字符,同时也不能用于非HTML的应用;但如果你希望HTML输出的源码文件能够具有更好的可读性,html_replace是非常有用的。

如果输出的不是HTML或者任何形式的XML,这些错误处理函数就没什么意义了。比如,TeX和其他的标记语言并不认识XML的数字字符引用,但如果你知道怎样创建一个该标记语言中的字符引用,可以修改本节示例中的错误处理函数html_replace,并注册一个新的符合需求的处理函数。

当需要将Unicode数据写入文件时,可以使用Python标准库的codecs模块提供的另一个(非常高效)可以指定编码和错误处理函数的方法:

outfile = codecs.open('out.html', mode='w', encoding='ascii',
                                   errors='html_replace')

现在,可以将outfile.write(unicode_data)应用于任何Unicode字符串unicode_data,所有的编码和错误处理都会透明地自动进行。当然,在输出完成之后,还得调用outfile.close()。

相关文章
|
4天前
|
数据处理 Python
如何使用Python的Pandas库进行数据排序和排名
【4月更文挑战第22天】Pandas Python库提供数据排序和排名功能。使用`sort_values()`按列进行升序或降序排序,如`df.sort_values(by=&#39;A&#39;, ascending=False)`。`rank()`函数用于计算排名,如`df[&#39;A&#39;].rank(ascending=False)`。多列操作可传入列名列表,如`df.sort_values(by=[&#39;A&#39;, &#39;B&#39;], ascending=[True, False])`和分别对&#39;A&#39;、&#39;B&#39;列排名。
14 2
|
3天前
|
机器学习/深度学习 数据挖掘 网络架构
Python对商店数据进行lstm和xgboost销售量时间序列建模预测分析
Python对商店数据进行lstm和xgboost销售量时间序列建模预测分析
15 0
|
4天前
|
机器学习/深度学习 算法 数据挖掘
PYTHON银行机器学习:回归、随机森林、KNN近邻、决策树、高斯朴素贝叶斯、支持向量机SVM分析营销活动数据|数据分享-2
PYTHON银行机器学习:回归、随机森林、KNN近邻、决策树、高斯朴素贝叶斯、支持向量机SVM分析营销活动数据|数据分享
28 1
|
3天前
|
机器学习/深度学习 算法 算法框架/工具
数据分享|PYTHON用KERAS的LSTM神经网络进行时间序列预测天然气价格例子
数据分享|PYTHON用KERAS的LSTM神经网络进行时间序列预测天然气价格例子
24 0
|
1天前
|
机器学习/深度学习 存储 监控
数据分享|Python卷积神经网络CNN身份识别图像处理在疫情防控下口罩识别、人脸识别
数据分享|Python卷积神经网络CNN身份识别图像处理在疫情防控下口罩识别、人脸识别
|
1天前
|
机器学习/深度学习 数据采集 算法
Python信贷风控模型:Adaboost,XGBoost,SGD, SVC,随机森林, KNN预测信贷违约支付|数据分享
Python信贷风控模型:Adaboost,XGBoost,SGD, SVC,随机森林, KNN预测信贷违约支付|数据分享
Python信贷风控模型:Adaboost,XGBoost,SGD, SVC,随机森林, KNN预测信贷违约支付|数据分享
|
1天前
|
JSON 数据可视化 定位技术
python_将包含汉字的字典数据写入json(将datav的全省数据中的贵州区域数据取出来)
python_将包含汉字的字典数据写入json(将datav的全省数据中的贵州区域数据取出来)
5 0
|
3天前
|
机器学习/深度学习 算法 Python
数据分享|Python决策树、随机森林、朴素贝叶斯、KNN(K-最近邻居)分类分析银行拉新活动挖掘潜在贷款客户
数据分享|Python决策树、随机森林、朴素贝叶斯、KNN(K-最近邻居)分类分析银行拉新活动挖掘潜在贷款客户
22 4
|
3天前
|
数据挖掘 数据处理 索引
如何使用Python的Pandas库进行数据筛选和过滤?
Pandas是Python数据分析的核心库,提供DataFrame数据结构。基本步骤包括导入库、创建DataFrame及进行数据筛选。示例代码展示了如何通过布尔索引、`query()`和`loc[]`方法筛选`Age`大于19的记录。
10 0
|
5天前
|
Python
如何使用Python的Pandas库进行数据缺失值处理?
Pandas在Python中提供多种处理缺失值的方法:1) 使用`isnull()`检查;2) `dropna()`删除含缺失值的行或列;3) `fillna()`用常数、前后值填充;4) `interpolate()`进行插值填充。根据需求选择合适的方法处理数据缺失。
39 9