尝试使用 ftplib 和 storbinary 存储 png 图像 ==> UnicodeEncodeError

Trying to store a png image using ftplib and storbinary ==> UnicodeEncodeError

我是 Whosebug 的新手,所以我真的很兴奋!

我的代码存在以下问题:我正在尝试将 'png' 图像存储到 FTP 服务器(网站的屏幕截图)中。

我正在使用 ftplib 和 selenium(带有 webdriver):

driver.get(<someURL>)
screenshot = driver.save_screenshot(driver.title + '.png')
ftp.storbinary("STOR <PathToServer>" + driver.title + '.png', open(driver.title + '.png', 'rb'))

当网站是拉丁字符时,此方法有效,问题是图像可能是位于泰国、中国或埃及等地的网站的屏幕截图。在这种情况下,带有:

的行
open(driver.title + '.png', 'rb')

returns 臭名昭著的错误:

UnicodeEncodeError: 'latin-1' codec can't encode character '\u1ec7' in position 60: ordinal not in range(256)

我知道 storbinary 只接受二进制数(正如该方法的名称所暗示的那样)。但是,我不明白的是我如何 "encode" png 以便它不会导致该错误,并且它可以成功存储到 FTP 服务器中。

非常感谢!任何帮助、评论或见解,将不胜感激。 最好!

事实是在 运行 计算机程序中表示的文本和存储在文件中的文本,文件名和数据库是两种不同的东西。人们可以将前者视为一组字符,而不用在意它们在内部是如何表示的。另一方面,要将此文本存储在文件系统 DB 中并通过网络传输,文本必须以字节表示。将程序为 运行 时的 "pure" 文本转换为字节表示的过程称为 "encoding"。为了更好地理解这一点,我建议阅读 this article.

Python 3,核心语言和库,在对文本进行任何 I/O 操作时,尝试自动 select 正确的文本编码。在您的情况下,它为目标服务器中的文件名选择了 "latin1" 编解码器。

Latin1 仅限于 200 多个有效字符,不能表示很多字符或字形 - 任何非西方语言字符,甚至一些西方字符,如 Ĺ、Ṕ、ŵ,都不能不能用它来表示。

建议在 Python 这样做之前对名称进行手动编码,因为这样我们就可以控制如何处理目标编码中不存在的字符。由于库方法 (.strobinary) 似乎期望文件名是一个字符串,因此,我们 "decode" 返回名称,但保留第一次编码时得到的无效字符的替换,并传递结果这次去图书馆的往返行程。

因此,为了保留 latin1 中不存在的关于您的字符的信息,我建议使用转义编码 - 其他选项是将 then 替换为“?”或忽略,只抑制所有字符:

filename = driver.title.encode("latin1", errors="xmlcharrefreplace").decode("latin1") + ".png"
screenshot = driver.save_screenshot(filename)
ftp.storbinary("STOR <PathToServer>" + filename, open(filename, 'rb'))