使用unicode以任何语言保存文件

时间:2014-12-23 15:25:52

标签: python python-2.7 unicode encoding reportlab

我正在使用Reportlab pdf生成模块创建一个简单的脚本,该脚本将图像列表作为输入并输出pdf文件。该脚本采用如上所示的文件名:

from reportlab.pdfgen import canvas
filename = raw_input("Enter pdf filename: ")
c = canvas.Canvas(filename + ".pdf")
c.save()

一切都很棒,直到用户输入非英语文件名(希伯来语,阿拉伯语),导致代码抛出以下异常:

UnicodeDecodeError: 'utf8' codec can't decode byte 0xf9 in position 0: invalid start byte

所以,我决定使用unicode,但是当我使用unicode()时,它会抛出另一个例外:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xf9 in position 0: ordinal not in range(128)

但是,当我解码字符串编码时,它就像一个魅力(希伯来语示例):

from reportlab.pdfgen import canvas
filename = raw_input("Enter pdf filename: ")
filename = filename.decode("windows-1255")
c = canvas.Canvas(filename + ".pdf")
c.save()

我继续尝试其他方法,并发现如果我在字符串u之前编写,如上例所示,它可以用任何语言工作:

from reportlab.pdfgen import canvas
filename = u"أ" #arabic
c = canvas.Canvas(filename + ".pdf")
c.save()

问题是我不知道我应该使用什么编码。输入字符串可以是任何语言。我该怎么做才能解决它,或者换句话说:如何在字符串之前添加u而无需编写编码?

PS:如果你有更好的头衔,请在下面写下我

编辑:文件名实际上是从网站提供的(我使用urllib)。我没想到这很重要,我用raw_input()来解决问题。对不起,

2 个答案:

答案 0 :(得分:5)

raw_input()字符串由终端或控制台编码,因此您可以要求终端或控制台使用正确的编解码器。

Python已经在启动时完成了这项工作,并将编解码器存储在sys.stdin.encoding

import sys

filename = raw_input("Enter pdf filename: ")
filename = filename.decode(sys.stdin.encoding)

从您发表的评论中,文件名实际上并非来自raw_input()。对于不同的来源,您需要使用不同的技术来检测所使用的字符集。

例如,HTTP响应可能charset标题中包含Content-Type参数; urlliburllib2响应可让您使用以下内容进行提取:

encoding = response.info().getparam('charset')

这仍然可以返回None,此时它取决于返回的确切mimetype。 text/ mimetypes(例如HTML)的默认值为Latin-1,但HTML标准还允许文档中的<meta>标题告诉您使用的字符集。对于HTML,我使用BeautifulSoup来解析响应,它会为你检测字符集。

如果没有关于实际如何从网址加载文件名的更多信息,我不能说更具体的内容。

答案 1 :(得分:1)

好的,我得到了解决方案!从服务器获取文本后,我使用BeutifulSoup解析它(谢谢@Martijn Pieters!),它有charset检测库:

resp = urllib2.urlopen("http://example.com").read() 
soup = BeautifulSoup(resp)
string = soup.find_all("span")[0].text

然后我只使用string作为文件名:

c = canvas.Canvas(path + "/" + string + ".pdf")

完全归功于推荐我使用BS的@Martijn Pieters。 这不是我编写的第一个脚本HTML解析脚本,而且我总是使用正则表达式。我强烈建议任何人使用BeautifulSoup,相信我它比正则表达式要好得多。