Niveau
Débutant
Env.
Local (Windows), Local (Linux), Google Colab
Code
Python
Libs
pyPDF2
Sources

Lire un fichier pdf avec Python

Dans la série des types de documents nous avons vu entres autre les fichiers structurés au format YAML. Mais qu’en est-il de l’un des formats de fichier texte les plus courant : le pdf ? comment récupérer les données de ce format semi-structuré et ce bien sur en toute simplicité ? Bien sur si vous tapez dans Google Python et pdf vous trouverez plusieurs librairies candidates pour manipuler ces fichier. Nous allons voir ensemble et dans ce court article comment utiliser l’une d’elle pyPDF2.

Qu’est-ce que pyPDF2 ?

PyPDF2 est une librairie Python trés utilisée permettant la lecture et quelques manipulations de fichiers au format pdf. Cette librairie est elle-même issue du projet pyPdf. Cette librairie est actuellement maintenue par Phaseit, Inc. et permet l’extraction des données provenant de fichiers PDF ou alors tout simplement manipuler des PDF existants dans l’idée de produire un nouveau fichier pdf (concaténation, filtrage de page, etc.). PyPDF2 est compatible avec les versions 2.6, 2.7 et 3.2 – 3.5 de Python.

NB: Utilisant la version 3.7 je n’ai pas rencontré de soucis particuliers …

L’installation est simple via l’utilitaire pip :

ShellSession
pip install pypdf2

Ouvrir un fichier pdf

L’utilisation de la librairie est plutôt simple et repose sur deux objets principaux : l’un en lecture et l’autre en écriture de fichier pdf.

Python
from PyPDF2 import PdfFileReader
from PyPDF2 import PdfFileWriter

Ensuite pour lire un fichier pdf, rien de plus simple, il suffit de l’ouvrir comme n’importe quel fichier en Python et d’utiliser l’objet PdfFileReader.

Nous allons dans le cadre de notre exemple lire un fichier très simple :

Contenu du fichier pdf
Python
document = PdfFileReader(open(myFile, 'rb'))

Le fichier est maintenant ouvert, regardons les méta-données :

Python
metadata = document.getDocumentInfo()
print (metadata)
{'/Author': 'Benoit Cayla',
 '/Creator': 'Microsoft® Word pour Office\xa0365',
 '/CreationDate': "D:20201110115707+01'00'",
 '/ModDate': "D:20201110115707+01'00'",
 '/Producer': 'Microsoft® Word pour Office\xa0365'}

On peut les récupérer aussi directement comme ceci :

Python
author = metadata.author if metadata.author else u'Unknown'
title = metadata.title if metadata.title else myFile
subject = metadata.subject if metadata.subject else "No Subject"
print (author + "|" + title + "|" + subject)
Benoit Cayla|test.pdf|No Subject

D’autres méthodes permettent de récupérer des informations importantes comme le nombre de page :

Python
print(document.getNumPages())
1

Récupération des champs interactifs :

Python
fields = document.getFields()

Mais aussi :

  • Le type d’affichage avec getPageLayout()
  • Le mode d’affichage avec getPageMode()

N’hésitez pas à consulter la documentation ici.

Lire le contenu du fichier pdf

On lit le contenu bien sur après avoir ouvert le fichier pdf avec PdfFileReader. Il faut bien sur tenir aussi compte de la pagination, la lecture se faisant page par page :

Python
pdftext = ""
for page in range(document.numPages):
    pageObj = document.getPage(page)
    pdftext += pageObj.extractText().replace('\n','')
Bonjour ceci est un test !  Benoit Cayla 

Vous remarquerez dans la dernière ligne que je retire les retours chariots (\n) car il sont récupérés tels quels par l’interpréteur.

Vous pouvez aussi regarder le détail (hiérarchique) des données qui ont été récupérées en affichant l’objet. Ce n’est pas d’une grande utilité tel quel mais celà vous montre que tout le contenu et méta-contenu à bien été récupéré.

Python
print(pageObj)
{'/Type': '/Page',
 '/Parent': {'/Type': '/Pages',
  '/Count': 3,
  '/Kids': [IndirectObject(3, 0), IndirectObject(4, 0), IndirectObject(5, 0)]},
 '/Resources': {'/Font': {'/F1': {'/Type': '/Font',
    '/Subtype': '/TrueType',
    '/Name': '/F1',
    '/BaseFont': '/BCDEEE+Calibri',
    '/Encoding': '/WinAnsiEncoding',
    '/FontDescriptor': {'/Type': '/FontDescriptor',
     '/FontName': '/BCDEEE+Calibri',
     '/Flags': 32,
     '/ItalicAngle': 0,
     '/Ascent': 750,
     '/Descent': -250,
     '/CapHeight': 750,
     '/AvgWidth': 521,
     '/MaxWidth': 1743,
     '/FontWeight': 400,
     '/XHeight': 250,
     '/StemV': 52,
     '/FontBBox': [-503, -250, 1240, 750],
     '/FontFile2': {'/Filter': '/FlateDecode', '/Length1': 93840}},
    '/FirstChar': 32,
    '/LastChar': 117,
    '/Widths': [226,
     0,
     ...
     0,
     525]}},
  '/ExtGState': {'/GS7': {'/Type': '/ExtGState', '/BM': '/Normal', '/ca': 1},
   '/GS8': {'/Type': '/ExtGState', '/BM': '/Normal', '/CA': 1}},
  '/ProcSet': ['/PDF', '/Text', '/ImageB', '/ImageC', '/ImageI']},
 '/MediaBox': [0, 0, 595.2, 841.92],
 '/Contents': {'/Filter': '/FlateDecode'},
 '/Group': {'/Type': '/Group', '/S': '/Transparency', '/CS': '/DeviceRGB'},
 '/Tabs': '/S',
 '/StructParents': 0}

Créons maintenant un nouveau fichier pdf

Dans cet exemple nous allons concaténer 3 fichiers pdf en un seul. Voici les 3 fichiers pdf que l’on va dans un premier temps ouvrir :

Python
pdflist = ["test.pdf" , "test2.pdf", "test3.pdf"]

Une fois ouvert, nous créons un nouveau fichier pdf avec PdfFileWriter:

Python
pdfWriter = PdfFileWriter()
for filename in pdflist:
    pdfFileObj = open(filename,'rb')
    pdfReader = PdfFileReader(pdfFileObj)
    for pageNum in range(pdfReader.numPages):
        pageObj = pdfReader.getPage(pageNum)
        pdfWriter.addPage(pageObj)
pdfOutput = open('final.pdf', 'wb')
pdfWriter.write(pdfOutput)
pdfOutput.close() 

Nous rajoutons simplement les pages des pdf existants dans le nouveau pdf.

Conclusion

Nous avons vu dans cet article comment et en toute simplicité on pouvait lire des données textuelles à partir d’un fichier pdf. Attention car nous sommes parti du principe que ces données étaient du « vrai » texte et non pas des images (scannées) de texte placées dans un pdf. Dans ce cas de figure, il faudrait alors extraire l’image du pdf puis ensuite utiliser un OCR tel que Tesseract. Pour celà je vous suggère de lire mon article ici.

Comme d’habitude vous trouverez les sources de cet article sur GitHub.

Partager cet article

9 Replies to “Lire un fichier pdf avec Python”

  1. Bonjour à tous,
    Je suis actuellement sur un projet dans le domaine du Machine Learning, le but est de faire une classification supervisée sur un ensemble de données. Mes données sont un grand nombre de fichiers pdf , chaque fichier à une classe precise, le but est d’utiliser ces fichiers la comme jeu de données d’apprentissage afin de faire de la prediction de la classe sur de nouveaux fichiers.
    Mon probléme c’est que je ne sais pas comment construire mon jeu de données d’entrainement vu que l’algrithme de classification doit s’entrainer sur le contenu de chaque fichier et dans mon data Frame d’entrainement j’ai la classe de chaque fichier et le nom du fichier en question. comment faire pour inclure le contenu de chaque fichier pdf dans mon Data Frame d’entrainement ?
    Merci par avance pour vorte aide

  2. Bonjour,
    Si j’ai bien compris votre question, il n’y a pas vraiment de soucis en réalité. Dans votre phase (partie de code) d’entraînement vous allez lire votre dataframe (pour recuperer le nom de fichier) et immédiatement lire le contenu du fichier, pour en exploiter directement le contenu … pas réellement besoin en fait de constituer un nouveau dataframe avec les features + labels puisque vous allez le construire à la volée.

  3. bonjour Monsieur,

    je suis un directeur commercial qui vient de commencer et comme vous le savez le budget assez serrer , j’ai bien envie une gestion de mais dossier sur pc en PDF avec un numéros et un nom , a ce jour je ne trouve pas un logiciel qui me convient , j’ai demander a un amis qui travaille sur java et a ce jour toujours pas réponse pas grave .
    on espérant avoir trouver une personne qui me comprend .

    cordialement

    M abdelatif

  4. Bonjour Benoît,
    Je reviens à la fouille de texte après quelques mois de développement web.
    DataCorner est toujours aussi instructif et permet en quelques minutes de découvrir de nouvelles librairies, de nouveaux outils.
    Merci pour ce travail partagé et longue vie à DataCorner.

    J-L Moiny.

  5. Bonjour.
    Merci beaucoup pour votre partage vous faites un bon travail.
    Pour ma part, j’ai 500 fichiers pdf de plan en format A4 qu’il me faut transformer en format tabloïd.
    Quelle bibliothèque python me conseillez vous ?
    Merci d’avance.

    1. Je n’ai pas de réponse évidente car il faudrait en savoir plus sur le contexte et sur les attentes en matière de temps de reponses, etc. D’ailleurs il faudra peut être plusoeurs librairies ? Sinon la librairie PyPDF2 est vraiment une bonne boite a outils pour pdf en python.

  6. Bonjour,
    J’ai un petit projet à faire.
    J’ai 2 gros dossiers où j’ai dans l’un plus de 300 fichiers PDF de 6 pages, et dans l’autre autant (ou moins mais jamais plus) de fichiers PDF de 2 pages.
    Mon but est de parcourir le contenu des fichiers des 2 dossiers et si je trouve la même référence, je dois les fusionner.
    EX. je lis le premier fichier de mon 1er dossier et puis je parcours le second dossiers pour trouver la même référence dans le contenu des fichiers et si je trouve la même référence, je les fusionne et l’enregistre ailleurs. (précision, je ne peux pas travailler avec le nom du fichier car je n’ai pas de référence).

    Est-ce réalisable avec pyPDF2 ?

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.