如何提取PDF文档的语言
我正在尝试用Python提取任何普通PDF文档的语言,并将其设置到内容管理系统(CMS)中。我是通过提取/Lang属性来实现的,下面是我的代码示例:
pdfFileLang = findInDict('/Lang',pdfFile.resolvedObjects())
def findInDict(needle,indirectObjectDict):
""" Returns the PDF Language """
haystack = indirectObjectDict[0]
LOG('pypdfutils.py getPdfLanguage key haystack',INFO,str(haystack))
for key in haystack.keys():
LOG('pypdfutils.py getPdfLanguage key',INFO,str(key))
try:
value = haystack[key]
LOG('pypdfutils.py getPdfLanguage value',INFO,str(value))
if key == needle:
return value
else:
LOG('pypdfutils.py getPdfLanguage value1',INFO,str(value))
internalDict = value.keys()
LOG('pypdfutils.py getPdfLanguage key Dict',INFO,str(internalDict))
if type(value) == types.DictType:
internalDict = value.keys()
else:
LOG('pypdfutils.py getPdfLanguage value2',INFO,str(value))
for internalkey in internalDict.keys():
internalvalue = internalDict[internalkey]
LOG('pypdfutils.py getPdfLanguage key internalvalue',INFO,str(internalvalue))
if type(internalvalue) == types.DictType and internalvalue.has_key(needle):
return internalvalue[needle]
except Exception,e:
LOG('pypdfutils.py getPdfLanguage',INFO,str(e))
continue
但是当我查看日志时,发现字典中没有这个"/Lang"属性。
2 个回答
在PDF规范中有说明:
文档目录里有一个叫“/Lang”的键。在我手上的PDF规范中,这部分在第7.7.2节有解释。
这个语言键定义了整个文档的假定语言,除了那些被标记为不同语言的部分。
所以,有两个注意事项:
1) 这个“/Lang”键是可选的。如果没有这个键,PDF规范就说语言是未定义的。
2) 这个“/Lang”键可能会被文件中的其他元素覆盖。所以整个文档可能是英语,但在第101页的某些句子可能会把语言重新定义为法语,比如说。
在你的情况下,你的算法应该首先尝试找到上面定义的整体文档语言。如果没有找到,那就看你想怎么做。你可以在整个文档中搜索“/Lang”键,看看有没有其他的,但如果找到多个,你就得决定这意味着什么……
看起来你是想在PDF文件中的所有字典里搜索'Lang'这个键。
要检查PDF文件中的语言信息,你需要查看目录里的'Lang'条目。不过,这个条目是否存在取决于用来创建PDF文件的软件,大多数PDF文件是没有这个条目的。
我对Python代码不太懂,但我相信你使用的PDF库会让你访问到文件的尾部(字典)或目录(根)字典。如果你能访问到尾部字典,就从中获取'Root'的值。这是指向目录(根)字典的间接引用。然后,你需要解析这个引用,找到目录字典。从这个目录字典中获取/Lang的值就能得到你想要的属性。
试试下面的代码:
catalog = pdfFile.trailer['/Root'].getObject()
if has_key("/Lang"):
lang = catalog['/Lang'].getObject()
请注意,我不是Python程序员,上面的代码片段是我写的第一段Python代码(我不确定它是否能工作。:-)
你可以参考pypdf的文档,链接在这里:http://sourcecodebrowser.com/python-pypdf/1.10/classpy_pdf_1_1pdf_1_1_pdf_file_reader.html#a92be75503c895367083a846b3060e632