Créer un navigateur web en Python avec PyQt5 : une fenêtre capable d’afficher des pages
Créer un navigateur web en Python ne signifie pas développer un nouveau Chrome. L’objectif réaliste est de construire une application de bureau capable de charger et d’afficher des pages web. Avec PyQt5 et PyQtWebEngine, quelques composants suffisent pour obtenir une fenêtre, une barre d’adresse, un bouton de validation et une vue web basée sur Chromium.
Navigateur, serveur web et page HTML : ne pas confondre les rôles
Un navigateur web est un client. Il reçoit une adresse URL, envoie une requête HTTP et interprète la réponse fournie par un serveur : HTML, feuilles de style, images, scripts et autres ressources. Dans ce tutoriel, Python pilote l’interface graphique, tandis que Qt WebEngine se charge du rendu de la page.
Vérifiez vos connaissances sur le navigateur Python
Un serveur web Python remplit le rôle inverse. Par exemple, python3 -m http.server expose le contenu d’un répertoire sur un port HTTP, souvent pour un test local. Il peut être consulté avec un navigateur, mais il n’affiche rien lui-même. Une application web, enfin, associe généralement un serveur, une logique métier et des pages servies aux clients.
| Élément | Rôle | Exemple |
|---|---|---|
| Navigateur Python | Demande et affiche les ressources web | Application PyQt5 avec QWebEngineView |
| Serveur web | Répond aux requêtes HTTP et fournit des fichiers | python3 -m http.server |
| Page HTML | Décrit le contenu à rendre dans le navigateur | Une page affichée depuis une URL ou localhost |
| HTTP | Organise l’échange entre client et serveur | Requête vers une adresse HTTPS |
Cette distinction aide à déboguer un projet. Si une page locale ne s’affiche pas, le problème peut venir du serveur lancé sur le mauvais port, de l’URL saisie dans le navigateur ou du fichier HTML lui-même. Séparer ces responsabilités évite de chercher une erreur d’interface dans le code du serveur.
Installer PyQt5 et le moteur web nécessaire
PyQt5 fournit les widgets de l’interface : fenêtre, champ de texte, bouton et menus. Pour afficher une vraie page web, il faut aussi installer PyQtWebEngine. Ce paquet contient notamment le module PyQt5.QtWebEngineWidgets et la classe QWebEngineView.
Dans un terminal ouvert dans votre environnement Python, installez les dépendances avec la commande suivante :
pip install PyQt5 PyQtWebEngine
Créez ensuite un fichier nommé navigateur.py. Le programme repose sur une organisation simple : une zone horizontale pour la saisie de l’URL et le bouton, puis une zone web qui occupe le reste de la fenêtre. QWebEngineView hérite de QWidget : il s’intègre donc dans un QVBoxLayout, un QHBoxLayout ou une grille.
| Classe | Utilité dans l’application |
|---|---|
| QApplication | Démarre la boucle d’événements Qt et maintient la fenêtre active. |
| QMainWindow | Fournit une fenêtre principale, compatible avec une barre de menus. |
| QWebEngineView | Affiche les pages web grâce au moteur de rendu Blink de Chromium. |
| QLineEdit | Recueille l’adresse saisie par l’utilisateur. |
| QPushButton | Déclenche la navigation par clic. |
| QMenuBar | Structure les actions générales, ici avec un menu de navigation. |
Le code d’un navigateur minimal, prêt à lancer
Recopiez les lignes suivantes dans navigateur.py, dans cet ordre. Le code ajoute automatiquement https:// lorsqu’aucun protocole n’est indiqué. Il associe aussi la touche Entrée et le bouton « Ouvrir » à la même méthode naviguer().
| Ligne | Contenu |
|---|---|
| 1 | import sys |
| 2 | from PyQt5.QtCore import QUrl |
| 3 | from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QLineEdit, QPushButton, QAction |
| 4 | from PyQt5.QtWebEngineWidgets import QWebEngineView |
| 5 | |
| 6 | class Navigateur(QMainWindow): |
| 7 | def __init__(self): |
| 8 | super().__init__() |
| 9 | self.setWindowTitle(« Mon navigateur Python ») |
| 10 | self.resize(1100, 750) |
| 11 | conteneur = QWidget() |
| 12 | mise_en_page = QVBoxLayout(conteneur) |
| 13 | barre = QHBoxLayout() |
| 14 | self.adresse = QLineEdit() |
| 15 | self.adresse.setPlaceholderText(« Saisissez une URL, par exemple example.org ») |
| 16 | bouton = QPushButton(« Ouvrir ») |
| 17 | barre.addWidget(self.adresse) |
| 18 | barre.addWidget(bouton) |
| 19 | self.vue = QWebEngineView() |
| 20 | mise_en_page.addLayout(barre) |
| 21 | mise_en_page.addWidget(self.vue) |
| 22 | self.setCentralWidget(conteneur) |
| 23 | bouton.clicked.connect(self.naviguer) |
| 24 | self.adresse.returnPressed.connect(self.naviguer) |
| 25 | self.vue.urlChanged.connect(lambda url: self.adresse.setText(url.toString())) |
| 26 | menu = self.menuBar().addMenu(« Navigation ») |
| 27 | retour = QAction(« Précédent », self) |
| 28 | retour.triggered.connect(self.vue.back) |
| 29 | menu.addAction(retour) |
| 30 | |
| 31 | def naviguer(self): |
| 32 | url = self.adresse.text().strip() |
| 33 | if url and « :// » not in url: |
| 34 | url = « https:// » + url |
| 35 | if url: |
| 36 | self.vue.setUrl(QUrl(url)) |
| 37 | |
| 38 | app = QApplication(sys.argv) |
| 39 | fenetre = Navigateur() |
| 40 | fenetre.show() |
| 41 | sys.exit(app.exec_()) |
Comprendre ce qui se passe lors d’une navigation
La méthode naviguer() récupère le contenu de QLineEdit avec text(), retire les espaces inutiles grâce à strip(), puis vérifie la présence d’un protocole. Une URL comme example.org devient ainsi https://example.org. La méthode setUrl() transmet enfin l’adresse sous la forme d’un objet QUrl à QWebEngineView.
Le signal returnPressed est émis lorsque l’utilisateur appuie sur Entrée dans la barre d’adresse. Le signal clicked est envoyé lors du clic sur le bouton. Relier ces deux événements à une seule méthode évite de dupliquer la logique et garantit le même comportement au clavier comme à la souris.
Le signal urlChanged met aussi à jour la barre d’adresse lorsque la page affichée change. C’est le cas après un clic sur un lien, une redirection ou un retour en arrière. L’utilisateur peut ainsi vérifier l’adresse correspondant à la page consultée, au lieu de conserver uniquement l’URL saisie au départ.
Tester le prototype et connaître ses limites
Lancez le programme depuis le terminal avec python navigateur.py. Saisissez ensuite une adresse HTTPS dans le champ, puis appuyez sur Entrée. Pour tester une page locale servie par Python, démarrez dans un autre terminal python3 -m http.server, puis ouvrez une adresse telle que http://localhost:8000.
Ce projet permet de découvrir Qt, HTTP et l’intégration d’un moteur de rendu web dans une application Python. Il ne remplace toutefois pas un navigateur complet : il ne gère pas encore les onglets, les favoris, l’historique persistant, les téléchargements, les permissions de sites ou les réglages de confidentialité.
- Ajoutez des actions « Suivant », « Actualiser » et « Accueil » dans QMenuBar.
- Prévoyez un message utilisateur lorsque l’URL est vide ou manifestement invalide.
- Testez les redirections et les pages HTTPS avant d’intégrer l’outil à un projet interne.
- Évitez d’exposer un serveur http.server sur un réseau non maîtrisé : il ne fournit par défaut ni chiffrement ni authentification.
- Créer un navigateur web en Python avec PyQt5 : une fenêtre capable d’afficher des pages - 1 octobre 2026
- ESB informatique : centraliser les flux sans multiplier les intégrations point-à-point - 30 septembre 2026
- REST ou SOAP : légèreté des API ou contrat XML formel ? - 29 septembre 2026



