xlrd - Ошибка "Книга зашифрована", Python 3.2.3
У меня есть небольшая программа, которая собирает список всех файлов.xls в папке / подпапках, а затем я перебираю список файлов, открывая каждый документ xls (Попробуйте: book = xlrd.open_workbook(f)), чтобы найти конкретную информацию, Если выдается исключение, я записываю имя файла в список исключений. Я обнаружил, что у меня много файлов, которые xlrd выдает ошибку:
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
book = xlrd.open_workbook(f)
File "C:\Python32\lib\site-packages\xlrd\__init__.py", line 435, in open_workbook
ragged_rows=ragged_rows,
File "C:\Python32\lib\site-packages\xlrd\book.py", line 116, in open_workbook_xls
bk.parse_globals()
File "C:\Python32\lib\site-packages\xlrd\book.py", line 1206, in parse_globals
self.handle_filepass(data)
File "C:\Python32\lib\site-packages\xlrd\book.py", line 924, in handle_filepass
raise XLRDError("Workbook is encrypted")
xlrd.biffh.XLRDError: Workbook is encrypted
Но я могу пойти и открыть файлы в Excel без проблем. У кого-нибудь есть идея относительно того, почему xlrd будет выдавать зашифрованную ошибку, когда не кажется, что файлы зашифрованы?
Спасибо,
Фред
1 ответ
Я столкнулся с этой же проблемой, и, как упомянул @zindorsky в своем комментарии, это может произойти, если у файла есть защищенный лист - или по какой-то другой причине, когда Excel молча зашифровал файл с помощью магического пароля. VelvetSweatshop
,
XLRD не может самостоятельно обрабатывать файлы с шифрованием (фактически README перечисляет это как "маловероятное"), но есть еще одна недавняя библиотека Python, которая может расшифровывать различные файлы MS Office (включая файлы.xls) - msoffcrypto-инструмент.
Я смог использовать его для успешного решения проблемы - вот сокращенная (и не проверенная!) Версия кода
import xlrd
import msoffcrypto
def handle_protected_workbook(wb_filepath):
try:
_book = xlrd.open_workbook(wb_filepath)
except xlrd.biffh.XLRDError, e:
if e.message == "Workbook is encrypted":
# Try and unencrypt workbook with magic password
wb_msoffcrypto_file = msoffcrypto.OfficeFile(open(wb_filepath, 'rb'))
try:
# Yes, this is actually a thing
# https://nakedsecurity.sophos.com/2013/04/11/password-excel-velvet-sweatshop/
wb_msoffcrypto_file.load_key(password='VelvetSweatshop')
except AssertionError, e:
if e.message == "Failed to verify password":
# Encrypted with some other password
raise # or do something else
else:
# Some other error occurred
raise
except:
# Some other error occurred
raise
else:
# Magic Excel password worked
assert wb_filepath.endswith('.xls')
wb_unencrypted_filename = wb_filepath[:-(len('.xls'))] + '__unencrypted.xls'
with tempfile.NamedTemporaryFile() as tmp_wb_unencrypted_file:
# Decrypt into the tempfile
wb_msoffcrypto_file.decrypt(tmp_wb_unencrypted_file)
# --- Do something with the file ---
# return true to indicate file was touched
return True # or do something else
else:
# some other xlrd error occurred.
return False # or do something else
except:
# some non-xlrd error occurred.
return False # or do something else
Основываясь на ответе Nuclearpidgeon, я создал диспетчер контекста, который прозрачно расшифровывает файлы по мере необходимости и заботится об очистке.
Использование:
with handle_protected_workbook(filepath) as wb:
# use wb
...
https://gist.github.com/terrdavis/b219e92d42dc5f9ca526aa0047d1a1d1