Antiword 无法打开 'C:\\?????? ????????\\info.doc' 用于在 Windows 中阅读 说明示例错误注意事项

问题描述

说明

我正在使用 texttract python 库来提取 Word 文档文本。问题是:如果路径包含阿拉伯字符,那么antiword输出无法读取文档。

示例

import textract

# path = 'C:\\test-docs\\info.doc'
path = 'C:\\مجلدات اختبارية\\info.doc'
text = textract.process(path,encoding='UTF-8')

print(text)

错误

Traceback (most recent call last):
  File "c:\test-extract-doc.py",line 5,in <module>
    text = textract.process(path,encoding='UTF-8')
  File "C:\Users\mohja\AppData\Local\Programs\Python\python39\lib\site-packages\textract\parsers\__init__.py",line 77,in process 
    return parser.process(filename,encoding,**kwargs)
  File "C:\Users\mohja\AppData\Local\Programs\Python\python39\lib\site-packages\textract\parsers\utils.py",line 46,in process    
    byte_string = self.extract(filename,**kwargs)
  File "C:\Users\mohja\AppData\Local\Programs\Python\python39\lib\site-packages\textract\parsers\doc_parser.py",line 9,in extract
    stdout,stderr = self.run(['antiword',filename])
  File "C:\Users\mohja\AppData\Local\Programs\Python\python39\lib\site-packages\textract\parsers\utils.py",line 100,in run       
    raise exceptions.ShellError(
textract.exceptions.ShellError: The command `antiword C:\مجلدات اختبارية\info.doc` Failed with exit code 1
------------- stdout -------------
b''------------- stderr -------------
b"I can't find the name of your HOME directory\r\nI can't open 'C:\\?????? ????????\\info.doc' for reading\r\n"

注意事项

  • 如果我使用 .docx 文档,该过程运行良好。
  • 如果我使用不含阿拉伯字符的目录名称,它也适用于 .doc 文档。

解决方法

深入研究 source code of textract 后,很明显,为了从 @Test @Sql(executionPhase = ExecutionPhase.BEFORE_TEST_METHOD,scripts="classpath:/scripts/init-scripts.sql") public void myTest() throws Exception {...} 中提取,使用了(古老的)命令行工具 antiword

.doc

Python 一切正常,但很明显 antiword 本身在解析参数的方式上存在问题,至少在 Windows 上,因此传递 Unicode 路径会导致损坏。

幸运的是,Windows 提供了一种将任何路径转换为仅 ANSI 8.3 文件名的向后兼容形式的方法 - 所谓的“短”路径,可以使用 Win32 API call 从系统请求。短路径和常规(“长”)路径可以互换,但旧版软件可能更喜欢短路径。

这提供了一种解决方法:检索任何 class Parser(ShellParser): """Extract text from doc files using antiword. """ def extract(self,filename,**kwargs): stdout,stderr = self.run(['antiword',filename]) return stdout 文件的短路径并将其提供给 antiword。 Win32 API 调用由 the win32api module 在 Python 中提供:

.doc

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...