Попытка сохранить изображение в формате png с использованием ftplib и storbinary ==> UnicodeEncodeError - PullRequest
1 голос
/ 03 октября 2019

Я новичок в StackOverflow, так что я действительно взволнован! 100

У меня возникла следующая проблема с моим кодом: я пытаюсь сохранить изображение png на FTP-сервере (снимок экрана веб-сайта).

Я используюftplib и selenium (с веб-драйвером):

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')

возвращает печально известную ошибку:

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

Я понимаю, что storbinary принимает только двоичные числа (как следует из названия этого метода). Однако я не понимаю, как я могу «закодировать» png, чтобы он не приводил к этой ошибке, и чтобы он мог успешно сохраняться на FTP-сервере.

Большое спасибомного! Любая помощь или комментарий, или понимание, будет высоко ценится. Лучший!

1 Ответ

0 голосов
/ 03 октября 2019

Факт - это текст, представленный в работающей компьютерной программе и сохраненный в файлах, именах файлов и базах данных - две разные вещи. Можно думать о первых как о наборе персонажей, не задумываясь о том, как они представлены внутри. С другой стороны, чтобы сохранить этот текст в файловой системе, БД, передать его по сети, текст должен быть представлен в байтах. Этот процесс преобразования «чистого» текста, который у вас есть, когда программа выполняется в байтовое представление, называется «кодированием». Для лучшего понимания, я предлагаю прочитать эту статью .

Python 3, как основной язык, так и библиотеки, попробуйте автоматически выбрать правильную кодировку текста при выполнении любого ввода-вывода с текстом,В вашем случае он выбрал кодек «latin1» для имен файлов на целевом сервере.

Latin1 ограничен немногим более 200 допустимыми символами и не может представлять много символов или глифов - любой символ не западного языка, и даже некоторые западные символы, такие как Ĺ, Ṕ, ŵ, могутне должны быть представлены вместе с ним.

Предлагается выполнить ручное кодирование имени перед тем, как сделать это с помощью Python, потому что тогда мы сможем управлять обработкой несуществующих символов в целевой кодировке. Поскольку библиотечный метод (.strobinary), похоже, ожидает имя файла в виде строки, то мы «декодируем» имя обратно, но сохраняем замены для недопустимых символов, которые мы получили при первом кодировании, и передаем результат этого туда и обратнобиблиотека.

Итак, чтобы сохранить информацию о ваших персонажах, которой нет в латинице 1, я бы предложил использовать escape-кодировку - другие варианты можно заменить на «?». или игнорировать, просто подавляя все символы:

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

...