【问题标题】:Remove non Unicode characters from xml database with Python使用 Python 从 xml 数据库中删除非 Unicode 字符
【发布时间】:2015-04-07 23:42:49
【问题描述】:

所以我有一个 9000 行的 xml 数据库,保存为 txt,我想在 python 中加载它,所以我可以做一些格式化并删除不必要的标签(我只需要一些标签,但有很多不必要的信息)以使其可读。但是,我收到了UnicodeDecodeError: 'charmap' codec can't decode byte 0x8d in position 608814: character maps to <undefined>,我认为这意味着程序遇到了非 Unicode 字符。我很肯定这些字符对程序并不重要(我要查找的数据都是纯文本,没有特殊符号),所以当我无法阅读时,如何从 txt 文件中删除所有这些字符没有得到UnicodeDecodeError的文件?

【问题讨论】:

  • 您如何尝试加载/阅读它?你知道它的编码是什么吗?另外,您使用的是什么版本的 Python?
  • 我将需要的 XML 数据库部分粘贴到 txt 中,然后使用 .read().splitlines() 获取列表,然后可以使用我编写的函数对其进行格式化逐行进行。
  • 复制和粘贴可能会弄乱字符编码,具体取决于您使用的工具。我将发布一个答案,说明如何跳过此异常,但这只会掩盖更大的问题。或者,如果您使用错误的编码打开文件,则会不必要地破坏信息。我想这有多重要取决于您的情况。
  • 我不知道数据库编码成什么。这是一个大型的短信数据库,彩信和表情符号已经被剥离。我正在使用 python 3.4.2。至于工具,我在 sublime text 2 中打开了 XML,复制了所有,除了开头附近的一些标签不包含我需要的文本。不过我对 XML 文件了解不多,所以我不知道如何解决这些问题,或者找出它的编码方式。

标签: python python-3.x unicode


【解决方案1】:

一种粗略的解决方法是自己解码文件中的字节并指定错误处理。例如:

for line in somefile:
    uline = line.decode('ascii', errors='ignore')

这会将行转换为 Unicode 对象,其中已删除任何非 ascii 字节。这不是一般推荐的方法——理想情况下,您希望使用适当的解析器处理 XML,或者至少知道文件的编码并适当地打开它(具体细节取决于您的 Python 版本)。但是,如果您完全确定您只关心 ascii 字符,那么这是一个简单的后备方案。

【讨论】:

  • 如何找到编码?
  • @Bretsky 如果没有人事先告诉您,您可以通过文件的来源猜测。例如,Windows 可能会使用cp1252
  • 一个很难的话题。我通常最终使用像od -c 这样的二进制显示程序来准确显示文件中的字节,然后根据经验缩小范围。在你的鞋子里,我会尝试open('somefile.txt', encoding='utf8') - 我认为这是 sublime 的默认设置。
  • 我在我的 Android 上使用了一个 SMS 备份应用程序,它创建了一个 XML 数据库。我只想要文本的正文、日期和发件人。
  • @Bretsky 来自 Android 然后utf-8 确实是一个不错的猜测。
【解决方案2】:

该错误表明您正在使用 open() 函数而未指定显式字符编码。在这种情况下使用locale.getpreferredencoding(False)(例如,cp1252)。该错误表明它不是输入的适当编码。

An xml document may contain a declaration at the very begining that specifies the encoding used explicitly. Otherwise the encoding is defined by BOM or it is utf-8. 如果您的复制粘贴和保存文件没有弄乱编码并且您没有看到诸如<?xml version="1.0" encoding="iso-8859-1" ?> 之类的行,则使用utf-8 打开文件:

with open('input-xml-like.txt', encoding='utf-8', errors='ignore') as file:
    ...

如果输入是一个实际的 XML,那么只需将其传递给 XML 解析器:

import xml.etree.ElementTree as etree

tree = etree.parse('input.xml')

【讨论】:

    猜你喜欢
    • 2015-04-23
    • 2019-11-26
    • 1970-01-01
    • 2018-09-03
    • 2016-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多