2012-02-10 53 views
1

在我正在开展的一个项目中,我们从各个政府网站上刮取法律文件,然后在线搜索它们。从腐败(?)中提取文本pdf文档

我们偶尔会遇到一个似乎是腐败的PDF。 Here's an example of one

如果你在一个PDF阅读器打开它,它看起来不错,但:

  • 如果您尝试复制和粘贴,你会损坏文本
  • 如果你通过像pdftotext任何工具运行,你已损坏的文本
  • 如果你做其它任何东西给它 - 你猜对了 - 你会损坏文本

然而,如果你在阅读器中打开它,它看起来很好!所以我知道文本在那里,但有些错误,错误的错误!结果就是在我的网站上看起来确实是不好。

有什么我可以做的吗?

更新:我今天做了更多的研究。感谢@Andrew Cash的观察,这实质上是一个凯撒密码,我意识到我可以搜索文件。 This link会在我的系统中向您显示约200个。看看更大的样本集,看起来这些都是由同一个软件创建的,pdffactory v。3.51!所以我责怪一个错误,而不是故意混淆。

更新2:上面的链接不再提供任何结果。这些从我的系统中使用我的解决方案清除。

+0

有很多种方法,以“混淆视听”的PDF文件,但如果他们正确地呈现在屏幕上,你应该能够谷歌“PDF OCR”,以找到一种产品,只会使它们并将它们转换为文本。其他选项是将它们转换为图像,例如Ghostscript,并使用几乎所有的OCR软件。 – 2012-02-10 07:31:29

+0

我会建议使用OCR程序。这样,你不会试图阅读一个潜在的腐败文件。 – 2012-02-10 07:32:27

回答

0

厌倦了这个问题,不想处理OCR,我手工整理了密码。在这里,她是一个python字典,还有一些我用来测试它的基本代码。我相信这可以得到改善,但它可以用于除大写字母Q和大写字母X之外的所有字母,这些字母我还没有找到。

它至少在目前还缺少一点标点符号(所有这些都丢失了,例如:<>?{} \ |!〜`@#$%^ _ = +)。

# -*- coding: utf-8 -*- 

import re 
import sys 

letter_map = { 
u'¿':'a', 
u'regex':'b', 
u'regex':'c', 
u'regex':'d', 
u'»':'e', 
u'o':'f', 
u'1':'g', 
u'regex':'h', 
u'·':'i', 
u'¶':'j', 
u'μ':'k', 
u'regex':'l', 
u'3':'m', 
u'2':'n', 
u'±':'o', 
u'°':'p', 
u'regex':'q', 
u'®':'r', 
u'-':'s', 
u'¬':'t', 
u'«':'u', 
u'a':'v', 
u'©':'w', 
u'regex':'x', 
u'§':'y', 
u'¦':'z', 
u'ß':'A', 
u'Þ':'B', 
u'Ý':'C', 
u'Ü':'D', 
u'Û':'E', 
u'Ú':'F', 
u'Ù':'G', 
u'Ø':'H', 
u'×':'I', 
u'Ö':'J', 
u'Õ':'K', 
u'Ô':'L', 
u'Ó':'M', 
u'Ò':'N', 
u'Ñ':'O', 
u'Ð':'P', 
u'':'Q', # Missing 
u'Î':'R', 
u'Í':'S', 
u'Ì':'T', 
u'Ë':'U', 
u'Ê':'V', 
u'É':'W', 
u'':'X', # Missing 
u'Ç':'Y', 
u'Æ':'Z', 
u'ð':'0', 
u'ï':'1', 
u'î':'2', 
u'í':'3', 
u'ì':'4', 
u'ë':'5', 
u'ê':'6', 
u'é':'7', 
u'è':'8', 
u'ç':'9', 
u'ò':'.', 
u'ô':',', 
u'æ':':', 
u'å':';', 
u'Ž':"'", 
u'•':"'", 
u'•':"'", # s/b double quote, but identical to single. 
u'Œ':"'", # s/b double quote, but identical to single. 
u'ó':'-', # dash 
u'Š':'-', # n-dash 
u'‰':'--', # em-dash 
u'ú':'&', 
u'ö':'*', 
u'ñ':'/', 
u'÷':')', 
u'ø':'(', 
u'Å':'[', 
u'Ã':']', 
u'‹':'•', 
} 

ciphertext = u'''YOUR STUFF HERE''' 

plaintext = '' 

for letter in ciphertext: 
    try: 
     plaintext += letter_map[letter] 
    except KeyError: 
     plaintext += letter 

# These are multi-length replacements 
plaintext = re.sub(u'm⁄4', 'b', plaintext) 
plaintext = re.sub(u'g⁄n', 'c', plaintext) 
plaintext = re.sub(u'g⁄4', 'd', plaintext) 
plaintext = re.sub(u' ́', 'l', plaintext) 
plaintext = re.sub(u' ̧', 'h', plaintext) 
plaintext = re.sub(u' ̈', 'x', plaintext) 
plaintext = re.sub(u' ̄u', 'qu', plaintext) 

for letter in plaintext: 
    try: 
     sys.stdout.write(letter) 
    except UnicodeEncodeError: 
     continue 
+0

你会发现这可能适用于这个特定的PDF,但将来你会看到不同的编码方案,并且在某些文档中,每种字体将使用不同的随机编码。 – 2012-02-11 02:28:10

+0

我不知道,我用这200个pdf文件,并做了一些抽查。无论出于何种原因,似乎完美地工作。 – mlissner 2012-02-11 04:32:53

+0

正如你所说,你的所有问题PDF都来自同一个制片人 - 很高兴听到这可以解决你的问题。 – 2012-02-12 14:51:00

2

Tha PDF正在使用子集字体,其中的字符被重新映射到其他字符使用相同的简单的二战替代密码。

A = G, B = 1, C =#, d = W, ... ...等等。每个角色都被重新映射。

字体以这种方式映射,并且为了在PDF中显示正确的字符,您需要发送“G1#W”来打印出ABCD。通常情况下,PDF的将有一个ToUnicode表格来帮助你提取文本,但这个表格被我故意遗漏了。

我已经看到这些文档中的一些我自己故意混淆以防止文本提取。我看过一个包含大约5种不同字体的文档,它们都使用不同的顺序进行映射。

确定这是否是问题的一个确定方法是将PDF加载到Acrobat中,并将文本复制/粘贴到文本编辑器中。如果Acrobat无法将文本解码为英文,那么如果您知道翻译映射,则无法手动重新提取文本。

从这些类型的文档中轻松提取文本的唯一方法是OCR整个文档并删除原始文本。 OCR会将页面转换为TIFF图像,然后进行OCR处理,所以原始乱码文本不应该影响OCR。

+0

没想到凯撒密码是这个的核心。不看故意 - 但看到我的更新。 – mlissner 2012-02-10 19:28:04

+0

哈哈哈....你对技术方面的解释是非常正确的(并且诚实的恭维:对于PDF-noobs也很容易理解)。但让我微笑的是,你正在编造一个关于“故意混淆”的阴谋论,它只是一个字体的“自定义编码”(被充分记录),它被获取子集(因为不想嵌入完整的字体,因为许可或空间考虑)。 ;-) – 2012-02-11 12:21:11