Как обнаружить страницы в файлах PDF, которые являются на самом деле двумя страницами?

У меня есть PDF (он не содержит отсканированные изображения), каждая страница которого - на самом деле две страницы, как это:

enter image description here

Однако существуют некоторые нормальные страницы, поэтому когда я записал программу для преобразования файла в нормальные страницы, я должен просмотреть файл путем прокрутки и определить страницы исключения и записать это в список так, чтобы программа могла знать конкретно, какая страница не включить половину (я использовал mutool для вырезания, он работает на этот тип файла).

Таким образом, как я могу обнаружить, какая страница нормальна и который не страница? Помогите мне, большое спасибо.

3
задан 29 March 2019 в 15:28

1 ответ

После проигрывания с несколькими утилитами от

poppler-utils

пакет, я наконец прибыл в приемлемое, но не оптимальный, решение.

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

pdftohtml

, который является инструментом от

poppler-utils

пакет, для преобразования каждой страницы в HTML, затем использует регулярное выражение для извлечения страниц, которые не удваивают страницы. Интересно, я смог получить большинство случаев правильно, просто используя одну или две строки в файле HTML. Это не работает над всеми случаями, поскольку существуют двойные страницы, которые отмечены как единственная страница, но кажется, что нет никакой единственной страницы, которая отмечена как двойная страница, таким образом, нет никакого риска повреждения исходного файла.

Вот то, что я сделал: Я главным образом зависел от обнаружения числа заголовка, которое находится в, почти заключает первую строку в корпус файла HTML (конечно, после нескольких строк, которые являются тем же через все страницы),

Я использовал то, что во введении файла, число заголовка использует римскую нумерацию, таким образом, я использовал соответствующий regex:

if re.findall('<a name=[0-9]*></a>[XIVLCDM]*<br/>', line) or \
                            re.findall('<a name=[0-9]*></a>[XIVLCDM]*&#[0-9]*;<br/>', line) or \
                            re.findall('<a name=[0-9]*></a>&#[0-9]*;[XIVLCDM]*&#[0-9]*;<br/>', line) or \
                            re.findall('<a name=[0-9]*></a>&#[0-9]*;[XIVLCDM]*<br/>', line):

Другая вещь, которую я заметил, состоит в том, что, если строка (на самом деле 31-я строка, так как первые 30 строк являются тем же через все страницы) содержит ссылку изображения затем, это, вероятно, не нужно, чтобы быть сокращенным в половине (существуют случаи, где левая страница является пробелом, и правильная страница содержит изображение, но они немногочисленны, таким образом, я просто должен выполнить итерации через каждую страницу в результате и удалить тех, которые являются двойной страницей). Я просто ищу строку "img".

Я также узнал, что двойные страницы содержат право числа заголовка вначале, таким образом, я просто использовал:

if re.findall('<a name=[0-9]*></a>&#[0-9]*;[0-9]*<br/>', line) or \
                                re.findall('<a name=[0-9]*></a>[0-9]*<br/>', line) or \
                                re.findall('<a name=[0-9]*></a>[0-9]*&#[0-9]*;<br/>', line) or \
                                re.findall('<a name=[0-9]*></a>&#[0-9]*;[0-9]*&#[0-9]*;<br/>', line) or \
                                re.findall('<a name=[0-9]*></a>V. &#160;I. &#160;L ª - n i n &#[0-9]*;<br/>', line):

(последняя строка происходит из-за некоторых специальных страниц тот специальный режим потребности),

В конце это не обнаруживает все единственные страницы, но хорошая вещь состоит в том, что это неправильно не рассматривает единственной страницы как двойную страницу, поэтому предполагает, что результат [1, 5, 100] затем я могу просто выполнить итерации через список и проверить визуально на каждый случай. Хотя это полностью все еще не автоматизировано, но это намного намного лучше, чем необходимость проверить каждую единственную страницу.

Для заинтересованных, вот мой код (в Python 2.7):

# -*- coding: utf-8 -*-
#!/usr/bin/python
#

import re
import pdb
import os
import errno
import subprocess

# Find pages that are not double page
# OS: Ubuntu
# Requirements: Python 2.7, pdftohtml


def silentremove(filename):
    try:
        os.remove(filename)
    except OSError as e:  # this would be "except OSError, e:" before Python 2.6
        if e.errno != errno.ENOENT:  # errno.ENOENT = no such file or directory
            raise  # re-raise exception if a different error occurred


num_of_pages = 395
input = "Lenin06.pdf"
excps = []
i = 1
with open(input, 'rt') as fid:
    while 1:
        if i > num_of_pages:
            break
        if (i == 1) or (i == 2):
            excps.append(str(i))
            i += 1
            continue
        if (i == 3) or (i == 4):
            i += 1
            continue
        cmd = "pdftohtml -i %s -f %d -l %d" % (input, i, i)
        os.system(cmd)
        html_file = input[:-4] + "s.html"
        with open(html_file, 'rt') as html_fid:
            for j in range(30):
                line = html_fid.readline()
            line = html_fid.readline()
            line = line.strip()

            if re.findall("img", line):
                excps.append(str(i))
            else:
                if re.findall('<a name=[0-9]*></a>&#[0-9]*;<br/>', line):
                    excps.append(str(i))
                else:
                    if re.findall('<a name=[0-9]*></a>[XIVLCDM]*<br/>', line) or \
                            re.findall('<a name=[0-9]*></a>[XIVLCDM]*&#[0-9]*;<br/>', line) or \
                            re.findall('<a name=[0-9]*></a>&#[0-9]*;[XIVLCDM]*&#[0-9]*;<br/>', line) or \
                            re.findall('<a name=[0-9]*></a>&#[0-9]*;[XIVLCDM]*<br/>', line):
                        # Loi tua (Introduction)
                        silentremove(input[:-4] + ".html")
                        silentremove(input[:-4] + "_ind.html")
                        silentremove(input[:-4] + "s.html")
                        i += 1
                        continue
                    else:
                        if re.findall('<a name=[0-9]*></a>&#[0-9]*;[0-9]*<br/>', line) or \
                                re.findall('<a name=[0-9]*></a>[0-9]*<br/>', line) or \
                                re.findall('<a name=[0-9]*></a>[0-9]*&#[0-9]*;<br/>', line) or \
                                re.findall('<a name=[0-9]*></a>&#[0-9]*;[0-9]*&#[0-9]*;<br/>', line) or \
                                re.findall('<a name=[0-9]*></a>V. &#160;I. &#160;L ª - n i n &#[0-9]*;<br/>', line):
                            # print "haha"
                            # Trang doi (Double page)
                            silentremove(input[:-4] + ".html")
                            silentremove(input[:-4] + "_ind.html")
                            silentremove(input[:-4] + "s.html")
                            i += 1
                            continue
                        else:
                            if re.findall('<a name=[0-9]*></a>[^0-9&#;]*&#160;<br/>', line) and \
                                    re.findall('^[0-9]*&#[0-9]*;<br/>$', html_fid.readline().strip()):
                                # 1 so truong hop trang trai trong, trang phai co chu
                                # (Some cases where the left page is blank while the right page contains
                                # text)
                                silentremove(input[:-4] + ".html")
                                silentremove(input[:-4] + "_ind.html")
                                silentremove(input[:-4] + "s.html")
                                i += 1
                                continue
                            else:
                                excps.append(str(i))
                        pass
                    pass
                pass
            silentremove(input[:-4] + ".html")
            silentremove(input[:-4] + "_ind.html")
            silentremove(input[:-4] + "s.html")
            i += 1
        pass
for file in os.listdir("./"):
    if file.endswith(".png") or file.endswith(".jpg") or file.endswith(".jpeg"):
        silentremove(file)
    pass
pdb.set_trace()

И это - файл: https://drive.google.com/open? id=1vjnebt3xEuY8odhZHPwL8pf26l8ySdnE (это - просто пример, я имею намного больше, который должен быть преобразован в единственные страницы),

2
ответ дан 1 December 2019 в 16:50

Другие вопросы по тегам:

Похожие вопросы: