【问题标题】:Trying to convert strings into unicode to load UFT-8 XML file尝试将字符串转换为 unicode 以加载 UTF-8 XML 文件
【发布时间】:2018-10-23 10:29:33
【问题描述】:

我正在构建一个创建 UTF-8 编码 XML 文件的 EPG 抓取工具。一切都很好,除了我无法将我正在拼接在一起的所有字符串位编码成一个可以加载到我的文件中的 unicode 字符串。

我的代码是这样的:

starttime = datetime.strptime(' '.join([str(now.year).encode('UTF-8'), str(e[4].encode('UTF-8')), str(e[0].encode('UTF-8'))]), '%Y %a %d %b %I:%M%p').strftime('%Y%m%d%H%M%S')
endtime = datetime.strptime(' '.join([str(now.year).encode('UTF-8'), str(e[4].encode('UTF-8')), str(e[1].encode('UTF-8'))]), '%Y %a %d %b %I:%M%p').strftime('%Y%m%d%H%M%S')

global epg_data

clean_channel = str(channel.encode('UTF-8').replace('&', '&amp;').replace("'", "&apos;").replace('"', '&quot;').replace('<', '&lt;').replace('>', '&gt;'))
clean_e2 = str(e[2].encode('UTF-8').replace('&', '&amp;').replace("'", "&apos;").replace('"', '&quot;').replace('<', '&lt;').replace('>', '&gt;'))
clean_e3 = str(e[3].encode('UTF-8').replace('&', '&amp;').replace("'", "&apos;").replace('"', '&quot;').replace('<', '&lt;').replace('>', '&gt;'))
div_list3 = div_list2.encode('UTF-8').replace('&', '&amp;').replace("'", "&apos;").replace('"', '&quot;').replace('<', '&lt;').replace('>', '&gt;')
e5 = str(e[5].encode('UTF-8').replace('&', '&amp;').replace("'", "&apos;").replace('"', '&quot;').replace('<', '&lt;').replace('>', '&gt;'))

epg_data = ''.join([u'<programme start="',starttime,u' +0100" stop="',endtime,u' +0100" channel="',clean_channel,u'">\n', \
u'<title lang="eng">',e5,u'</title>\n<desc lang="eng">',clean_e2,' ',clean_e3,u'</desc>\n<icon src="',div_list3,u'" />\n', \
u'<country>UK</country>\n</programme>'])

我在尝试解析以下内容时遇到问题(打印到 IDLE):

<programme start="20180514180500 +0100" stop="20180514190000 +0100" channel="BBC Entertainment">
<title lang="eng">Hustle</title>
<desc lang="eng">Hustle Tiger Troubles Season 6 Episode 3/6When a notorious hardman demands £500,000 from Albert by the end of the week, the team tries to raise the cash by targeting a playboy in possession of a gold tiger worth a vast amount of money. Emma is sent to persuade the owner to lend the item to a major museum, in the hope the gang can steal it, but an impenetrable vault causes complications. Guest starring former Doctor Who star Colin Baker and Lolita Chakrabarti : 8.2</desc>
<icon src="http://my.tvguide.co.uk/channel_logos/60x35/68.png" />
<country>UK</country>
</programme>

产生的错误是这样的:

Traceback (most recent call last):
  File "G:\Python27\Kodi\Sky TV Guide Scraper.py", line 332, in soup_to_text
    u'<country>UK</country>\n</programme>'])
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 75: ordinal not in range(128)

我在整理这件事上有点迷失方向,因此我们将不胜感激地收到任何帮助。

谢谢

【问题讨论】:

  • 如何保存文件?以后怎么解析?解析器似乎正在尝试 ascii。尝试将"&lt;?xml version=“1.0” encoding=“utf-8”?&gt;\n" 添加到 xml 的顶部。
  • 您使用 python 2 的任何原因? Python 3 已经存在了近十年,并且具有更好的 unicode 支持。
  • 稍后会在程序中添加正确的标题。问题在此之前就已经存在了。问题是尝试将 ascii 字符串转换为 unicode,如上所述。关于如何解决的任何想法?
  • 实际上,我相信添加这行代码已经解决了我的问题:'epg_data2 = unicode(epg_data, 'UTF-8')'
  • 您不是将 ascii 转换为 unicode,而是将 utf-8 编码的二进制转换为 unicode。您的修复工作的原因是它解码了 utf-8 编码的字符串。但你不应该做所有这些工作。从您的原始代码中删除 utf-8 内容并始终使用 unicode。

标签: python xml unicode utf-8


【解决方案1】:

Unicode 支持在 python 2 中相当令人困惑。这是迁移到 python 3 的前 50 个理由。将str 或 unicode 编码为 utf-8 会返回一个 str 对象,该对象与常规 ASCII 无法区分细绳。你只需要记住它的编码。 str(channel.encode('utf-8')) 有点多余(它已经是 str 所以 str(..) 部分不是必需的。

当您调用''.join([u'&lt;programme start="', etc...]) 时,您混合了unicode 和str 对象,因此python 尝试将所有内容提升为unicode。您知道其中一些 str 字符串实际上是 utf-8 编码的字符串,但 python 不知道这一点。 Python 3 会知道这一点并且会大声吠叫。

unicode 的一般规则是在边缘进行转换。读入时解码,写出时编码。如果您跳过了 encode('utf-8') 的内容,只是在您提供的 sn-p 中坚持使用 unicode,那么它会起作用。

另外两件事要考虑:Python 可以为您转义字符串。 cgi.escpae 适用于较旧的 HTML。 xml.sax.saxutils.escape 适用于 XML、XHTML 和 HTML5。而str.format 可以帮助制作更易读的字符串格式。

把它们放在一起......

starttime = datetime.strptime(' '.join([now.year, e[4], e[0], '%Y %a %d %b %I:%M%p').strftime('%Y%m%d%H%M%S')
endtime = datetime.strptime(' '.join([now.year, e[4], e[1]]), '%Y %a %d %b %I:%M%p').strftime('%Y%m%d%H%M%S')

global epg_data

epg_data = u"""\
<programme start="{starttime} +0100" stop="{endtime} +0100" channel="{channel}">
    <title lang="eng">{e5}</title>
    <desc lang="eng">{e2} {e3}</desc>
    <icon src="{div_list2}" />
    <country>UK</country>
</programme>""".format(channel=escape(channel), starttime=starttime, 
    endtime=endtime,e5=escape(e5), e2=escape(e2), e3=escape(e3), 
    div_list2=escape(div_list2))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-02
    • 2010-09-21
    • 1970-01-01
    • 2021-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-02
    相关资源
    最近更新 更多