问题描述
说明
我正在使用 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