Comment travailler avec un PDF en Python
Le format PDF ou Portable Document Format est un format de fichier qui peut être utilisé pour présenter et échanger des documents de manière fiable entre les systèmes d'exploitation. Alors que le PDF a été inventé à l'origine par Adobe, c'est maintenant unopen standard qui est maintenu par l'Organisation internationale de normalisation (ISO). Vous pouvez travailler avec un PDF préexistant en Python en utilisant le packagePyPDF2
.
PyPDF2
est un packagepure-Python que vous pouvez utiliser pour de nombreux types différents d'opérations PDF.
À la fin de cet article, vous saurez comment effectuer les opérations suivantes:
-
Extraire les informations d'un document à partir d'un PDF en Python
-
Faire pivoter les pages
-
Fusionner des PDF
-
Diviser les PDF
-
Ajouter des filigranes
-
Chiffrer un PDF
Commençons!
Free Bonus:Click here to get access to a chapter from Python Tricks: The Book qui vous montre les meilleures pratiques de Python avec des exemples simples que vous pouvez appliquer instantanément pour écrire du code + Pythonic plus beau.
Historique depyPdf
,PyPDF2
etPyPDF4
Le package originalpyPdf
a été publié en 2005. La dernière publication officielle depyPdf
remonte à 2010. Après une période d'environ un an, une société appeléePhasit a sponsorisé une fourchette depyPdf
appeléePyPDF2
. Le code a été écrit pour être rétrocompatible avec l'original et a très bien fonctionné pendant plusieurs années, sa dernière version étant en 2016.
Il y a eu une brève série de versions d'un package appeléPyPDF3
, puis le projet a été renommé enPyPDF4
. Tous ces projets font à peu près la même chose, mais la plus grande différence entrepyPdf
et PyPDF2 + est que ces dernières versions ont ajouté la prise en charge de Python 3. Il existe un fork de Python 3 différent despyPdf
for Python 3d'origine, mais celui-ci n'a pas été maintenu depuis de nombreuses années.
Alors quePyPDF2
a été récemment abandonné, le nouveauPyPDF4
n'a pas une rétrocompatibilité totale avecPyPDF2
. La plupart des exemples de cet article fonctionneront parfaitement avecPyPDF4
, mais il y en a qui ne le peuvent pas, c'est pourquoiPyPDF4
n'est pas présenté plus en détail dans cet article. N'hésitez pas à échanger les importations contrePyPDF2
avecPyPDF4
et voyez comment cela fonctionne pour vous.
pdfrw
: une alternative
Patrick Maupin a créé un package appelépdfrw
qui peut faire beaucoup des mêmes choses quePyPDF2
. Vous pouvez utiliserpdfrw
pour tous les mêmes types de tâches que vous apprendrez à faire dans cet article pourPyPDF2
, à l'exception notable du chiffrement.
La plus grande différence en ce qui concernepdfrw
est qu'il s'intègre au packageReportLab afin que vous puissiez prendre un PDF préexistant et en créer un nouveau avec ReportLab en utilisant tout ou partie du PDF préexistant.
Installation
L'installation dePyPDF2
peut être effectuée avecpip
ouconda
si vous utilisez Anaconda au lieu de Python classique.
Voici comment installerPyPDF2
avecpip
:
$ pip install pypdf2
L'installation est assez rapide carPyPDF2
n'a aucune dépendance. Vous passerez probablement autant de temps à télécharger le package que vous l'installerez.
Continuons et apprenons à extraire des informations d'un fichier PDF.
Comment extraire les informations d'un document à partir d'un PDF en Python
Vous pouvez utiliserPyPDF2
pour extraire des métadonnées et du texte d'un PDF. Cela peut être utile lorsque vous effectuez certains types d'automatisation sur vos fichiers PDF préexistants.
Voici les types actuels de données qui peuvent être extraites:
-
Auteur
-
Créateur
-
Producteur
-
Matière
-
Titre
-
Nombre de pages
Vous devez aller chercher un PDF à utiliser pour cet exemple. Vous pouvez utiliser n'importe quel PDF que vous avez à portée de main sur votre machine. Pour simplifier les choses, je suis allé àLeanpub et j'ai pris un échantillon d'un de mes livres pour cet exercice. L'échantillon que vous souhaitez télécharger s'appellereportlab-sample.pdf
.
Écrivons du code à l'aide de ce PDF et apprenons comment vous pouvez accéder à ces attributs:
# extract_doc_info.py
from PyPDF2 import PdfFileReader
def extract_information(pdf_path):
with open(pdf_path, 'rb') as f:
pdf = PdfFileReader(f)
information = pdf.getDocumentInfo()
number_of_pages = pdf.getNumPages()
txt = f"""
Information about {pdf_path}:
Author: {information.author}
Creator: {information.creator}
Producer: {information.producer}
Subject: {information.subject}
Title: {information.title}
Number of pages: {number_of_pages}
"""
print(txt)
return information
if __name__ == '__main__':
path = 'reportlab-sample.pdf'
extract_information(path)
Ici, vous importezPdfFileReader
du packagePyPDF2
. LePdfFileReader
est une classe avec plusieurs méthodes pour interagir avec les fichiers PDF. Dans cet exemple, vous appelez.getDocumentInfo()
, qui renverra une instance deDocumentInformation
. Il contient la plupart des informations qui vous intéressent. Vous appelez également.getNumPages()
sur l'objet lecteur, qui renvoie le nombre de pages du document.
Note: Ce dernier bloc de code utilise les nouvelles f-strings de Python 3 pour le formatage des chaînes. Si vous souhaitez en savoir plus, vous pouvez consulterPython 3’s f-Strings: An Improved String Formatting Syntax (Guide).
La variableinformation
a plusieurs attributs d'instance que vous pouvez utiliser pour obtenir le reste des métadonnées que vous souhaitez du document. Vous imprimez ces informations et les retournez également pour une utilisation future potentielle.
Alors quePyPDF2
a.extractText()
, qui peut être utilisé sur ses objets de page (non représentés dans cet exemple), cela ne fonctionne pas très bien. Certains PDF renvoient du texte et d'autres renvoient une chaîne vide. Lorsque vous souhaitez extraire du texte d'un PDF, vous devez plutôt consulter le projetPDFMiner
. PDFMiner
est beaucoup plus robuste et a été spécialement conçu pour extraire du texte à partir de PDF.
Vous êtes maintenant prêt à en savoir plus sur la rotation des pages PDF.
Comment faire pivoter les pages
Parfois, vous recevrez des fichiers PDF contenant des pages enlandscape mode au lieu du mode portrait. Ou peut-être qu'ils sont même à l'envers. Cela peut se produire lorsque quelqu'un numérise un document au format PDF ou par e-mail. Vous pouvez imprimer le document et lire la version papier ou vous pouvez utiliser la puissance de Python pour faire pivoter les pages incriminées.
Pour cet exemple, vous pouvez choisir un Real Pythonarticle et l'imprimer au format PDF.
Apprenons à faire pivoter certaines des pages de cet article avecPyPDF2
:
# rotate_pages.py
from PyPDF2 import PdfFileReader, PdfFileWriter
def rotate_pages(pdf_path):
pdf_writer = PdfFileWriter()
pdf_reader = PdfFileReader(path)
# Rotate page 90 degrees to the right
page_1 = pdf_reader.getPage(0).rotateClockwise(90)
pdf_writer.addPage(page_1)
# Rotate page 90 degrees to the left
page_2 = pdf_reader.getPage(1).rotateCounterClockwise(90)
pdf_writer.addPage(page_2)
# Add a page in normal orientation
pdf_writer.addPage(pdf_reader.getPage(2))
with open('rotate_pages.pdf', 'wb') as fh:
pdf_writer.write(fh)
if __name__ == '__main__':
path = 'Jupyter_Notebook_An_Introduction.pdf'
rotate_pages(path)
Pour cet exemple, vous devez importer lesPdfFileWriter
en plus dePdfFileReader
car vous devrez écrire un nouveau PDF. rotate_pages()
prend le chemin vers le PDF que vous souhaitez modifier. Dans cette fonction, vous devrez créer un objet écrivain que vous pourrez nommerpdf_writer
et un objet lecteur appelépdf_reader
.
Ensuite, vous pouvez utiliser.GetPage()
pour obtenir la page souhaitée. Ici, vous récupérez la page zéro, qui est la première page. Ensuite, vous appelez la méthode.rotateClockwise()
de l'objet page et passez à 90 degrés. Ensuite, pour la page deux, vous appelez.rotateCounterClockwise()
et passez-le également à 90 degrés.
Note: Le packagePyPDF2
vous permet uniquement de faire pivoter une page par incréments de 90 degrés. Sinon, vous recevrez unAssertionError
.
Après chaque appel aux méthodes de rotation, vous appelez.addPage()
. Cela ajoutera la version pivotée de la page à l'objet écrivain. La dernière page que vous ajoutez à l'objet écrivain est la page 3 sans aucune rotation.
Enfin, vous écrivez le nouveau PDF en utilisant.write()
. Il prend unfile-like object comme paramètre. Ce nouveau PDF contiendra trois pages. Les deux premiers seront tournés dans des directions opposées et seront en paysage tandis que la troisième page est une page normale.
Voyons maintenant comment fusionner plusieurs PDF en un seul.
Comment fusionner des PDF
Il existe de nombreuses situations où vous souhaiterez prendre deux PDF ou plus et les fusionner en un seul PDF. Par exemple, vous pouvez avoir une page de garde standard qui doit passer à de nombreux types de rapports. Vous pouvez utiliser Python pour vous aider à faire ce genre de chose.
Pour cet exemple, vous pouvez ouvrir un PDF et imprimer une page en tant que PDF séparé. Recommencez ensuite, mais avec une autre page. Cela vous donnera quelques entrées à utiliser à des fins d'exemple.
Continuons et écrivons du code que vous pouvez utiliser pour fusionner des PDF:
# pdf_merging.py
from PyPDF2 import PdfFileReader, PdfFileWriter
def merge_pdfs(paths, output):
pdf_writer = PdfFileWriter()
for path in paths:
pdf_reader = PdfFileReader(path)
for page in range(pdf_reader.getNumPages()):
# Add each page to the writer object
pdf_writer.addPage(pdf_reader.getPage(page))
# Write out the merged PDF
with open(output, 'wb') as out:
pdf_writer.write(out)
if __name__ == '__main__':
paths = ['document1.pdf', 'document2.pdf']
merge_pdfs(paths, output='merged.pdf')
Vous pouvez utilisermerge_pdfs()
lorsque vous avez une liste de fichiers PDF que vous souhaitez fusionner. Vous devrez également savoir où enregistrer le résultat, donc cette fonction prend une liste de chemins d'entrée et un chemin de sortie.
Ensuite, vous bouclez sur les entrées et créez un objet lecteur PDF pour chacune d'entre elles. Ensuite, vous parcourez toutes les pages du fichier PDF et utilisez.addPage()
pour ajouter chacune de ces pages à elle-même.
Une fois que vous avez fini d'itérer sur toutes les pages de tous les PDF de votre liste, vous noterez le résultat à la fin.
Un élément que je voudrais souligner est que vous pouvez améliorer un peu ce script en ajoutant une plage de pages à ajouter si vous ne souhaitez pas fusionner toutes les pages de chaque PDF. Si vous souhaitez relever un défi, vous pouvez également créer une interface de ligne de commande pour cette fonction en utilisant le moduleargparse
de Python.
Voyons comment faire le contraire de la fusion!
Comment diviser des PDF
Il y a des moments où vous pouvez avoir un PDF que vous devez diviser en plusieurs PDF. Cela est particulièrement vrai pour les PDF qui contiennent beaucoup de contenu numérisé, mais il existe une multitude de bonnes raisons de vouloir diviser un PDF.
Voici comment vous pouvez utiliserPyPDF2
pour diviser votre PDF en plusieurs fichiers:
# pdf_splitting.py
from PyPDF2 import PdfFileReader, PdfFileWriter
def split(path, name_of_split):
pdf = PdfFileReader(path)
for page in range(pdf.getNumPages()):
pdf_writer = PdfFileWriter()
pdf_writer.addPage(pdf.getPage(page))
output = f'{name_of_split}{page}.pdf'
with open(output, 'wb') as output_pdf:
pdf_writer.write(output_pdf)
if __name__ == '__main__':
path = 'Jupyter_Notebook_An_Introduction.pdf'
split(path, 'jupyter_page')
Dans cet exemple, vous créez à nouveau un objet de lecteur PDF et bouclez sur ses pages. Pour chaque page du PDF, vous allez créer une nouvelle instance de rédacteur PDF et y ajouter une seule page. Ensuite, vous écrirez cette page dans un fichier au nom unique. Une fois le script terminé, vous devez diviser chaque page du PDF d'origine en PDF distincts.
Voyons maintenant comment ajouter un filigrane à votre PDF.
Comment ajouter des filigranes
Les filigranes identifient des images ou des motifs sur des documents imprimés et numériques. Certains filigranes ne sont visibles que dans des conditions d'éclairage spéciales. La raison pour laquelle le filigrane est important est qu'il vous permet de protéger votre propriété intellectuelle, comme vos images ou vos PDF. Un autre terme pour filigrane est superposition.
Vous pouvez utiliser Python etPyPDF2
pour filigraner vos documents. Vous devez avoir un PDF contenant uniquement votre image ou texte en filigrane.
Voyons maintenant comment ajouter un filigrane:
# pdf_watermarker.py
from PyPDF2 import PdfFileWriter, PdfFileReader
def create_watermark(input_pdf, output, watermark):
watermark_obj = PdfFileReader(watermark)
watermark_page = watermark_obj.getPage(0)
pdf_reader = PdfFileReader(input_pdf)
pdf_writer = PdfFileWriter()
# Watermark all the pages
for page in range(pdf_reader.getNumPages()):
page = pdf_reader.getPage(page)
page.mergePage(watermark_page)
pdf_writer.addPage(page)
with open(output, 'wb') as out:
pdf_writer.write(out)
if __name__ == '__main__':
create_watermark(
input_pdf='Jupyter_Notebook_An_Introduction.pdf',
output='watermarked_notebook.pdf',
watermark='watermark.pdf')
create_watermark()
accepte trois arguments:
-
input_pdf
: le chemin du fichier PDF à filigraner -
output
: le chemin dans lequel vous souhaitez enregistrer la version filigranée du PDF -
watermark
: un PDF contenant votre image ou texte de filigrane
Dans le code, vous ouvrez le PDF en filigrane et prenez uniquement la première page du document car c'est là que votre filigrane doit résider. Ensuite, vous créez un objet lecteur PDF en utilisant lesinput_pdf
et un objet génériquepdf_writer
pour écrire le PDF filigrané.
L'étape suivante consiste à parcourir les pages dans lesinput_pdf
. C'est là que la magie opère. Vous devrez appeler.mergePage()
et lui transmettre leswatermark_page
. Lorsque vous faites cela, il superposera leswatermark_page
en haut de la page actuelle. Ensuite, vous ajoutez cette page nouvellement fusionnée à votre objetpdf_writer
.
Enfin, vous écrivez le nouveau PDF en filigrane sur le disque et vous avez terminé!
Le dernier sujet que vous apprendrez est la façon dontPyPDF2
gère le chiffrement.
Comment crypter un PDF
PyPDF2
ne prend actuellement en charge que l'ajout d'un mot de passe utilisateur et d'un mot de passe propriétaire à un PDF préexistant. Dans PDF Land, un mot de passe propriétaire vous donnera essentiellement des privilèges d'administrateur sur le PDF et vous permettra de définir des autorisations sur le document. D'un autre côté, le mot de passe utilisateur vous permet simplement d'ouvrir le document.
Pour autant que je sache,PyPDF2
ne vous permet pas de définir d’autorisations sur le document, même s’il vous permet de définir le mot de passe du propriétaire.
Quoi qu'il en soit, voici comment vous pouvez ajouter un mot de passe, qui cryptera également le PDF de manière inhérente:
# pdf_encrypt.py
from PyPDF2 import PdfFileWriter, PdfFileReader
def add_encryption(input_pdf, output_pdf, password):
pdf_writer = PdfFileWriter()
pdf_reader = PdfFileReader(input_pdf)
for page in range(pdf_reader.getNumPages()):
pdf_writer.addPage(pdf_reader.getPage(page))
pdf_writer.encrypt(user_pwd=password, owner_pwd=None,
use_128bit=True)
with open(output_pdf, 'wb') as fh:
pdf_writer.write(fh)
if __name__ == '__main__':
add_encryption(input_pdf='reportlab-sample.pdf',
output_pdf='reportlab-encrypted.pdf',
password='twofish')
add_encryption()
prend les chemins d'accès PDF d'entrée et de sortie ainsi que le mot de passe que vous souhaitez ajouter au PDF. Il ouvre ensuite un écrivain PDF et un objet lecteur, comme précédemment. Étant donné que vous souhaiterez crypter l'intégralité du PDF d'entrée, vous devrez parcourir toutes ses pages et les ajouter à l'auteur.
La dernière étape consiste à appeler.encrypt()
, qui prend le mot de passe de l'utilisateur, le mot de passe du propriétaire et si oui ou non un cryptage de 128 bits doit être ajouté. Par défaut, le cryptage 128 bits doit être activé. Si vous le définissez surFalse
, le cryptage 40 bits sera appliqué à la place.
Le cryptage PDF deNote: utilise RC4 ou AES (Advanced Encryption Standard) pour crypter le PDF selonpdflib.com.
Ce n'est pas parce que vous avez chiffré votre PDF qu'il est nécessairement sécurisé. Il existe des outils pour supprimer les mots de passe des PDF. Si vous souhaitez en savoir plus, l’Université Carnegie Mellon a unpaper on the topic intéressant.
Conclusion
Le packagePyPDF2
est assez utile et est généralement assez rapide. Vous pouvez utiliserPyPDF2
pour automatiser les gros travaux et tirer parti de ses capacités pour vous aider à mieux faire votre travail!
Dans ce didacticiel, vous avez appris à effectuer les opérations suivantes:
-
Extraire les métadonnées d'un PDF
-
Faire pivoter les pages
-
Fusionner et fractionner des PDF
-
Ajouter des filigranes
-
Ajouter un cryptage
Gardez également un œil sur le nouveau packagePyPDF4
car il remplacera probablementPyPDF2
bientôt. Vous pouvez également consulterpdfrw
, qui peut faire beaucoup des mêmes choses quePyPDF2
peut faire.
Lectures complémentaires
Si vous souhaitez en savoir plus sur l'utilisation des fichiers PDF en Python, vous devriez consulter certaines des ressources suivantes pour plus d'informations: