使用zipfile库解压docx文件提示“非zip文件”的问题求助
我刚碰到过一模一样的坑!你遇到的zipfile.BadZipFile错误根本不是文件的问题——手动改zip能解压就说明文件本身是合法的压缩包,问题出在你打开文件的方式上!
问题根源
默认的open()函数是用文本模式打开文件的,而docx本质是二进制的zip压缩包,文本模式会自动转换换行符等二进制数据,破坏了压缩包的结构,导致zipfile识别失败。
两种解决方案
方案1:直接用二进制模式打开(推荐,最简单)
不需要重命名任何文件,只需要把open()的模式改成'rb'(read binary)就行,这是最直接的解决办法。
修正后的完整代码:
import zipfile from lxml import etree import pandas as pd FILE_PATH = 'C:/Users/user/Documents/Python Project' class Application(): def __init__(self): print('Initialized!') xml_content = self.get_word_xml(f'{FILE_PATH}/DocxFile.docx') xml_tree = self.get_xml_tree(xml_content) # 接下来就可以基于xml_tree解析表格,转成pandas DataFrame了 def get_word_xml(self, docx_filename): # 核心修改:用二进制模式'rb'打开文件 with open(docx_filename, 'rb') as f: zip_ref = zipfile.ZipFile(f) xml_content = zip_ref.read('word/document.xml') return xml_content def get_xml_tree(self, xml_string): return etree.fromstring(xml_string) if __name__ == "__main__": a = Application() # 原代码里的a.mainloop()看起来是tkinter的方法,如果不是GUI程序可以去掉
方案2:自动重命名文件(不推荐,但满足需求)
如果你非要通过重命名的方式来实现,也可以在代码里临时把docx复制成zip文件,用完再删掉(避免污染原文件):
import zipfile from lxml import etree import pandas as pd import os import shutil FILE_PATH = 'C:/Users/user/Documents/Python Project' class Application(): def __init__(self): print('Initialized!') xml_content = self.get_word_xml(f'{FILE_PATH}/DocxFile.docx') xml_tree = self.get_xml_tree(xml_content) def get_word_xml(self, docx_filename): # 生成临时zip文件名 temp_zip = docx_filename.replace('.docx', '.zip') # 复制原docx文件为zip(不修改原文件) shutil.copy(docx_filename, temp_zip) try: # 同样要以二进制模式打开 with open(temp_zip, 'rb') as f: zip_ref = zipfile.ZipFile(f) xml_content = zip_ref.read('word/document.xml') finally: # 用完删除临时文件 os.remove(temp_zip) return xml_content def get_xml_tree(self, xml_string): return etree.fromstring(xml_string) if __name__ == "__main__": a = Application()
你之前的报错堆栈
Traceback (most recent call last):
File "C:\Users\user\Documents\New_Tool.py", line 39, in
a = Application()
File "C:\Users\user\Documents\New_Tool.py", line 27, in init
xml_content = self.get_word_xml(f'{FILE_PATH}/DocxFile.docx')
File "C:\Users\user\Documents\New_Tool.py", line 32, in get_word_xml
zip = zipfile.ZipFile(f)
File "C:\Progra~1\Anaconda3\lib\zipfile.py", line 1222, in init
self._RealGetContents()
File "C:\Progra~1\Anaconda3\lib\zipfile.py", line 1289, in _RealGetContents
raise BadZipFile("File is not a zip file")
zipfile.BadZipFile: File is not a zip file
内容的提问来源于stack exchange,提问作者Maximus3537

