2012-08-10 16 views
8

Ho bisogno di analizzare un documento PDF. Ho già implementato il parser e ho utilizzato la libreria iText e fino ad ora ha funzionato senza problemi.Strani spazi bianchi durante l'analisi di un PDF

Ma no, ho bisogno di analizzare un altro documento che ottiene degli strani spazi molto bizzarri nel mezzo delle parole. A titolo di esempio ottengo:

Vo rber Zeitung auf die Motorr adsaison. Viele Motorr Ahr adf er

Tutte le parole in grassetto devono essere collegati, ma in qualche modo il parser PDF è l'aggiunta di spazi bianchi nelle parole. Ma quando copio e incollo il contenuto dal PDF in un file di testo non ottengo questi spazi.

Prima ho pensato che fosse a causa della libreria di analisi PDF che sto utilizzando, ma anche con un'altra libreria ottengo lo stesso identico problema.

Ho dato un'occhiata allo singleSpaceWidth dalle parole analizzate e ho notato che è sempre variabile quando aggiunge uno spazio bianco. Ho provato a metterli manualmente insieme. Ma dal momento che non c'è davvero un modello per ricombinare le parole è quasi impossibile.

Qualcun altro ha un problema simile o addirittura una soluzione a tale problema?

Come richiesto, ecco qualche informazione in più:

analisi con SemTextExtractionStrategy:

PdfReader reader = new PdfReader("data/SpecialTests/SuedostSchweiz/" + src); 

SemTextExtractionStrategy semTextExtractionStrategy = new SemTextExtractionStrategy(); 

for (int i = 1; i <= reader.getNumberOfPages(); i++) { 
    // Set the page number on the strategy. Is used in the Parsing strategies. 
    semTextExtractionStrategy.pageNumber = i; 

    // Parse text from page 
    PdfTextExtractor.getTextFromPage(reader, i, semTextExtractionStrategy); 
} 

Qui il metodo SemTextExtractionStrategy che effettivamente analizza il t ext. Ci aggiungo manualmente dopo ogni parola analizzata uno spazio bianco, ma in qualche modo lo fa dividere le parole del rilevamento:

@Override 
public void parseText(TextRenderInfo renderInfo, int pageNumber) {  

    this.pageNumber = pageNumber; 

    String text = renderInfo.getText(); 

    currTextBlock.getText().append(text + " "); 

    .... 
} 

Ecco tutta la classe SemTextExtraction ma lì lo fa solo chiamare il metodo dall'alto (parseText):

public class SemTextExtractionStrategy implements TextExtractionStrategy { 

    // Text Extraction Strategies 
    public ColumnDetecter columnDetecter = new ColumnDetecter(); 

    // Image Extraction Strategies 
    public ImageRetriever imageRetriever = new ImageRetriever(); 

    public int pageNumber = -1; 

    public ArrayList<TextParsingStrategy> textParsingStrategies = new ArrayList<TextParsingStrategy>(); 
    public ArrayList<ImageParsingStrategy> imageParsingStrategies = new ArrayList<ImageParsingStrategy>(); 

    public SemTextExtractionStrategy() { 

     // Add all text parsing strategies which are later on applied on the extracted text 
     // textParsingStrategies.add(fontSizeMatcher); 
     textParsingStrategies.add(columnDetecter); 

     // Add all image parsing strategies which are later on applied on the extracted text 
     imageParsingStrategies.add(imageRetriever); 
    } 

    @Override 
    public void beginTextBlock() { 

    } 

    @Override 
    public void renderText(TextRenderInfo renderInfo) { 
     // TEXT PARSING 
     for(TextParsingStrategy strategy : textParsingStrategies) { 
      strategy.parseText(renderInfo, pageNumber); 
     } 
    } 

    @Override 
    public void endTextBlock() { 

    } 

    @Override 
    public void renderImage(ImageRenderInfo renderInfo) { 
     for(ImageParsingStrategy strategy : imageParsingStrategies) { 
      strategy.parseImage(renderInfo); 
     } 
    } 
} 
+0

indica la versione di iText che stai utilizzando e, in qualche modo, devi fornire anche il PDF e il codice con cui esegui l'analisi. – Eugene

+0

Aggiunte tutte le informazioni nel post in alto. – Prine

+0

e la classe TextExtractionStrategy che usi? – Eugene

risposta

2

ho elaborato il file PDF dato con il Ghostscript seguente comando:

gs -o out.pdf -q -sDEVICE=pdfwrite -dOptimize=false -dUseFlageCompression=false -dCompressPages=false -dCompressFonts=false whitespacesProblem.pdf 

Questo comando creato un file out.pdf, che non ha le codifiche flusso, quindi è meglio leggibile. La parte interessante è in linea 52, che ho diviso in più righe per migliorare la leggibilità:

[ 
    (&;&)-287.988 
    (672744)29.9906 
    (+\(%)30.01 
    (+!4)29.9876 
    (&4)-287.989 
    (%4)30.0039 
    (&1&8)-287.975 
    (3=\)!)-288.021 
    (*&4)30.0212 
    (&=23)-287.996 
    (+1%)-287.99 
    (\(=&)-288.011 
    (8&1&)-287.974 
    (672744)29.9906 
    (+\(3+=378$)-250.977 
    (#7\)!) 
]TJ 

tra le parentesi sono i caratteri di testo. Ho modificato alcuni di essi e ho visto il file PDF reso per vedere quale personaggio rappresenta quale glifo. Poi ho decodificato il testo:

[ 
    (ele)-287.988 
    (Motorr)29.9906 *** 
    (adf)30.01 *** 
    (ahr)29.9876 *** 
    (er)-287.989 
    (fr)30.0039 
    (euen)-287.975 
    (sich)-288.021 
    ... 
] 

Quindi c'è davvero spazio tra i caratteri. Nel tuo caso questa è probabilmente la crenatura del font. La domanda ora è come la tua libreria PDF interpreti questo spazio bianco, e mi sembra, che anche "spazio negativo negativo" sia reso in uno spazio nella stringa risultante.

+0

C'è un modo per sbarazzarsi di questa o di un'implementazione? – NinjaOnSafari

+0

e quale strumento hai usato per generare il pdf? – NinjaOnSafari

+0

È Ghostscript; Ho modificato la risposta per renderlo chiaro. Grazie per il suggerimento. –

0

Poiché il documento che si ha è diviso in colonne, l'errore evidente è all'interno del

SemTextExtractionStrategy

classe. Suppongo che la classe ColumnDetecter sia quella probabilmente da incolpare e non iText. Posso solo supporre che sia implementato in base alla dimensione della colonna, quindi recupera il testo in base a quello.

Se si desidera solo il testo, l'implementazione potrebbe essere più semplice, in base alle dimensioni della Colonna.

+0

Grazie per la risposta. Darò sicuramente un'occhiata a ColumnDetecter. Ma il metodo parseText è di questa classe e lì ottengo l'output direttamente dalla libreria iText in cui le parole sono già divise .. – Prine

1

Gli spazi vuoti in pdf sono un problema noto, come descritto dalla risposta qui da Roland e anche visto in un primo commento del https://issues.apache.org/jira/browse/TIKA-724

La risposta che ha lavorato anche per me è quello visto da huuhungus a https://github.com/smalot/pdfparser/issues/72

che è specifico per PDFParser ed è quello di cambiare il codice che in realtà aggiunge questo spazio extra per il PDFParser se sai che avrà questo problema:

sr c/Smalot/PdfParser/Object.php commentare questa linea

$text .= ' '; 

Non del tutto risolvere il problema, ma è a accettabili

Altre biblioteche può anche avere gli aggiornamenti temporanei simili in modo da poter aiutare con questo problema in alcuni casi.

+0

iText 5.2.1 è una versione antica ora. Le versioni correnti hanno proprietà/metodi sovrascrivibili per mettere a punto le situazioni in cui iText aggiunge uno spazio e in cui no. Mai aggiungere uno spazio è una cattiva scelta in generale, numerosi PDF quindi il loro testo verrà estratto con pochissimi spazi. – mkl