27 giugno 2019

ricerca nei PDF, Python e Apache Tika

Questa settimana, al lavoro, ho dovuto rovistare nella spazzatura informatica, un compito apparentemente lungo e ingrato, ma che mi ha dato l'opportunità di conoscere uno strumento nuovo.

Il compito consisteva nell'analizzare un migliaio di file senza estensione e con nomi casuali (GUID) per attribuirgli l'estensione corretta e un nome basato sul contenuto che consentisse di identificare quelli utili, da conservare e quelli da scartare.

Nella mia scatola degli attrezzi, per fare questi lavoretti in ambiente Windows, utilizzo spesso il linguaggio Python. Nel caso specifico ho utilizzato la versione 3.6.

Disclaimer/Avvertenza: non sono un programmatore Python. Ho assemblato i programmini qui sotto in pochi minuti, modificando codice trovato su Internet. Non garantisco né per la correttezza, né per lo stile! 

Ricerca e memorizzazione del tipo di file

Con uno script in Python posso passare uno ad uno i file senza estensione e cercare nei caratteri iniziali qualche sigla, tipo "Magic Number" o "shebang" che mi dice che tipo di file sto elaborando.

Nello specifico si trattava di file PDF (estensione .pdf), Excel 2013 (estensione .xlsx) e XML (estensione .xml). Trascrivo il codice specifico per i file pdf.


import os

mydir = "./temp"
directory = os.fsencode(mydir)
print(directory)

substring = "%PDF"                #pdf

for file in os.listdir(directory):
    filename = os.fsdecode(file)
    filenamefullpath = os.path.join(mydir, filename)
    file_extension = os.path.splitext(file)[1]

    if not file_extension:

        # Open the file with read only permit
        f = open(filenamefullpath, encoding="Latin-1")
        found = False
        linen = 0
        # use readline() to read the first line
        line = f.readline()

        while (line and not found and linen<3):
            if linen == 0:
                print(filename)

            if substring in line:
                print ("Your substring was found!")
                found = True

            else:
                # use readline() to read next line
                line = f.readline()
                linen += 1

        f.close()

        if found:
            os.rename(filenamefullpath, filenamefullpath + '.pdf')

    else:
        continue

Così ho identificato i file pdf. Rimane da leggere il pdf per capire che tipo di documento è, e se il contenuto è utile.


Embed from Getty Images

Ricerca del contenuto

Se apro un pdf con un editor di testo (il mio preferito è Notepad++) non riesco a trovare il testo che vedo quando apro il pdf con un lettore di pdf come Adobe Acrobat Reader.  Il testo è nascosto o ricodificato in maniera da non essere immediatamente ricercabile come caratteri ASCII.

Ho tentato diverse strade, tra cui xpdf_python, che però si è immediatamente rivelata infruttuosa perché in Windows falliva l'installazione del modulo.

Grazie a Stack Overflow, ho trovato altri suggerimenti, tra cui l'utilizzo della libreria Apache Tika, che per vostra convenienza e cultura ho anche documentato su Wikipedia.


import os

from tika import parser

mydir = "./temp"

directory = os.fsencode(mydir)

print(directory)

substring = "RAPPORTO ANNUALE"                #RA

filename_prefix = 'RA-'

for file in os.listdir(directory):
    filename = os.fsdecode(file)
    filenamefullpath = os.path.join(mydir, filename)
    file_extension = os.path.splitext(file)[1]

    if file_extension == b".pdf":
        raw = parser.from_file(filenamefullpath)
        text = raw['content']
        # print(raw['content'])
        found = False

        if substring in text:
            print ("Your substring was found!")
            found = True

        if found:
            filenamenew = filename_prefix + filename
            filenamefullpathnew = os.path.join(mydir, filenamenew)
            os.rename(filenamefullpath, filenamefullpathnew)

    else:
        continue

Il codice andrebbe commentato, ma non vorrei annoiarvi.

Vi confesso che sono rimasto molto ben impressionato dalle funzionalità di Tika, che mi ha consentito di automatizzare rapidamente un lavoro da incubo se fatto a mano.