Извлечь текст из поврежденного (?) PDF-документа - PullRequest
1 голос
/ 10 февраля 2012

В проекте, над которым я работаю, мы собираем юридические документы с различных правительственных сайтов, а затем делаем их доступными для поиска в Интернете.

Время от времени мы сталкиваемся с PDF, который кажется поврежденным. Вот пример одного .

Если вы откроете его в PDF-ридере, он выглядит хорошо, но:

  • Если вы попытаетесь скопировать и вставить его, вы получите поврежденный текст
  • Если вы запускаете его с помощью любых инструментов, таких как pdftotext, вы испортили текст
  • Если вы делаете что-то еще - вы уже догадались - вы получите искаженный текст

Тем не менее, если вы откроете его в считывающем устройстве, оно будет выглядеть хорошо! Так что я знаю, что текст есть, но что-то не так, не так! В результате на моем сайте это выглядит действительно плохо.

Могу ли я что-нибудь сделать?

Обновление: Сегодня я провел дополнительные исследования. Благодаря замечанию @Andrew Cash о том, что это по сути шифр Цезаря, я понял, что могу искать документы. Эта ссылка покажет вам около 200 из них в моей системе. Просматривая больший набор образцов, кажется, что все они созданы одним и тем же программным обеспечением, pdffactory v. 3.51! Так что я виню в ошибке, а не в преднамеренном запутывании.

Обновление 2: Ссылка выше не даст никаких результатов. Они удаляются из моей системы с использованием моего решения ниже.

Ответы [ 2 ]

2 голосов
/ 10 февраля 2012

Tha PDF использует заданные шрифты, в которых символы переназначаются на другие символы, используя то же самое, что и простой заменитель Второй мировой войны.

A = G, B = 1, C = #, D = W, ... ... и так далее.Каждый символ переназначается.

Шрифт отображается таким образом, и для получения правильных символов, отображаемых в PDF, вам необходимо отправить «G1 # W», чтобы распечатать ABCD.Обычно в PDF есть таблица ToUnicode, чтобы помочь вам с извлечением текста, но я подозреваю, что эта таблица была опущена.

Я сам видел несколько таких документов, где они намеренно запутаны, чтобы предотвратить извлечение текста.Я видел документ с примерно 5 различными шрифтами, и все они были отображены с использованием различной последовательности.

Один верный способ определить, является ли это проблемой, заключается в загрузке PDF-файла в Acrobat и копировании / вставке текста втекстовый редактор.Если Acrobat не может декодировать текст обратно на английский, то нет способа извлечь текст, не переназначив его вручную, если вы знаете сопоставления перевода.

Единственный способ легко извлечь текст из документов этого типа - распознать полный документ и удалить исходный текст.OCR преобразует страницу в изображение TIFF, а затем OCR, чтобы исходный искаженный текст не влиял на OCR.

1 голос
/ 11 февраля 2012

Устав от этой проблемы и не желая иметь дело с OCR, я вручную разобрался с шифром.Вот она, как Python dict вместе с неким элементарным кодом, который я использовал для его тестирования.Я уверен, что это можно улучшить, но он работает для всех букв, кроме прописных 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
...