我正在使用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()
来解决问题。对不起,
答案 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
参数; urllib
或urllib2
响应可让您使用以下内容进行提取:
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,相信我它比正则表达式要好得多。