Относительно ошибки сопоставления Unicode при разборе pdf - PullRequest
4 голосов
/ 06 августа 2020

У меня есть куча pdf-файлов (из разных источников), и я хотел бы извлечь из них текст (к сожалению, не могу прикрепить файлы).

Текущий результат синтаксического анализа :

  1. Tika молча возвращает текст, в котором отсутствует много необходимых данных.
  2. Использование PDFBox напрямую выдает кучу предупреждений (см. Ниже), а также удаляет данные, которые он не мог распознать
  3. Adobe Acrobat Reader (действие «Сохранить как текст») сохраняет исходную структуру документа, но вместо проблемных c шрифтов помещает «??????»

Все комбинированные предупреждения, которые я вижу до сих пор, из PDFBox:

Aug 06, 2020 3:10:49 PM org.apache.pdfbox.pdmodel.font.PDType0Font toUnicode
WARNING: No Unicode mapping for CID+51 (51) in font AUDQZE+OpenSans-Identity-H

Aug 06, 2020 3:10:49 PM org.apache.pdfbox.pdmodel.font.PDType0Font toUnicode
WARNING: No Unicode mapping for CID+5 (5) in font HCUDUN+DroidSerif-Identity-H

Aug 06, 2020 3:10:49 PM org.apache.pdfbox.pdmodel.font.PDType0Font toUnicode
WARNING: No Unicode mapping for CID+5 (5) in font AUDQZE+OpenSans-Identity-H

Aug 06, 2020 3:10:49 PM org.apache.pdfbox.pdmodel.font.PDType0Font toUnicode
WARNING: No Unicode mapping for CID+55 (55) in font GFEIIG+OpenSans

Aug 06, 2020 3:10:49 PM org.apache.pdfbox.pdmodel.font.PDType0Font toUnicode
WARNING: No Unicode mapping for CID+5 (5) in font GFEIIF+DroidSerif

Aug 06, 2020 3:10:50 PM org.apache.pdfbox.pdmodel.font.PDType0Font toUnicode
WARNING: No Unicode mapping for CID+5 (5) in font GFEIIG+OpenSans

В идеале я бы хотел использовать Tika, так как я ожидаю форматов Word и HTML.

Вопрос : Итак, мне было интересно, могу ли я попросить Tika (или PDFBox) использовать другое отображение кодировки, такое как ASCII, чтобы убедиться, что эти проблемные шрифты c могут быть проанализированы с помощью альтернативы таблице Unicode?

Вот Нашел следующее:

Почему я получаю gibberi sh (G38G43G36G51G5) при извлечении текста? Это связано с тем, что символы в документе PDF могут использовать пользовательскую кодировку вместо Unicode или ASCII. Когда вы видите текст gibberi sh, это, вероятно, означает, что используется бессмысленная внутренняя кодировка. Единственный способ получить доступ к тексту - использовать OCR. Это может быть улучшением в будущем.

^ Означает ли это, что нижележащий PDFBox уже проверяет кодировку ASCII для шрифта, и мне вообще не нужно беспокоиться об ASCII?

Тупой вопрос : Могу ли я каким-то образом предоставить недостающее отображение Unicode в PDFBox? Используете Тику? Скажем, у меня ограниченное количество известных сбоев сопоставлений Unicode, могу ли я каким-то образом передать такую ​​информацию синтаксическому анализатору?

Мой случай : у меня уже есть куча документов (поэтому нет контроля над созданием) Я Я хотел бы выполнить поиск, поэтому я решил создать их индекс с помощью Tika. Я предполагаю, что большая часть файла pdf будет иметь проблему с не встроенным шрифтом. Так что потенциально я подумал об использовании свойства Tika Metadata.get(UNMAPPED_UNICODE_CHARS_PER_PAGE), чтобы решить, требуется ли им анализ OCR Tika (pdfConfig.setOcrStrategy(OCR_STRATEGY.OCR_ONLY)) после анализа NO_OCR. OCR в 10 раз медленнее и менее точное (оно также считывает изображения, такие как lo go, и пытается понять его, хотя это не нужно и просто добавляет шум), но я не вижу других вариантов.

Оцените любые мысли по этому поводу, спасибо.

UPD

Спасибо @mkl за указание на введение отображения шрифтов перед синтаксическим анализом. Интересно, можно ли автоматизировать это, если у меня есть шрифты (файлы TTF), с помощью которых был создан PDF-файл?

Фрагменты кода, которые я использую для синтаксического анализа, если это поможет:

Tika:

static void parseAndPrint(String fileName) throws IOException, TikaException {
    Tika tika = new Tika();
    InputStream is = Main.class.getResourceAsStream(fileName);
    System.out.println(tika.parseToString(is));
}

PDFBox:

static void parseAndPrint(String fileName) throws IOException {
    System.out.println("========= Start File: " + fileName);
    InputStream file = Main.class.getResourceAsStream(fileName);
    PDFTextStripper tStripper = new PDFTextStripper();
    PDDocument document = PDDocument.load(file);
    System.out.print(tStripper.getText(document));
    document.close();
    System.out.println("========= End File: " + fileName);
}
...