Créer un navigateur web en Python : une fenêtre, une barre d’adresse et un moteur Chromium

Créer un navigateur web en Python : une fenêtre, une barre d’adresse et un moteur Chromium

Pour créer un navigateur web en Python, vous pouvez associer PyQt5 pour l’interface graphique et PyQtWebEngine pour afficher les pages. Vous obtenez une application de bureau avec une barre d’adresse, un bouton de navigation et une vue web. Il ne s’agit pas de lancer un serveur : votre programme joue le rôle du client qui consulte les sites.

L’exemple ci-dessous propose une base exécutable, puis explique les mécanismes à comprendre pour l’adapter sans confondre interface graphique et moteur de navigation.

Définir ce que votre navigateur va réellement faire

Un navigateur reçoit une adresse, demande des ressources à un serveur et affiche leur contenu. HTTP organise ces échanges ; HTML décrit la structure des pages. Le moteur de rendu interprète ensuite le document, les styles et les autres ressources nécessaires à son affichage.

Quiz sur la création d’un navigateur web en Python

Répondez aux six questions, puis validez pour voir votre score et les corrections.

Réponses sélectionnées : 0 / 6 Score : — / 6
1. Quel est le rôle de PyQt5 dans ce projet ?
2. À quoi sert PyQtWebEngine ?
3. Quelle est la fonction de QWebEngineView ?
4. Quand le signal returnPressed est-il émis ?
5. À quoi sert QUrl.fromUserInput ?
6. Quelle commande permet de lancer le fichier navigateur.py ?

Avec Python, vous n’allez pas réécrire ce moteur. QWebEngineView intègre une vue web reposant sur Qt WebEngine et Chromium, dont le moteur de rendu est Blink. Votre travail consiste surtout à construire les commandes autour de cette vue.

ÉlémentRôleDans ce projet
Navigateur webDemande et affiche des ressourcesVotre application PyQt5
Serveur webRépond aux requêtes du navigateurUn site distant ou un serveur local
Application webFournit une interface et des fonctionnalités accessibles dans un navigateurLe service consulté, pas la fenêtre Python

Le module Python http.server répond donc à un autre besoin : servir des fichiers. Il peut aider à tester votre navigateur, mais ne crée ni fenêtre ni barre d’adresse. Les mécanismes serveur comme CGI ne sont pas nécessaires ici.

Installer les dépendances dans le bon environnement

Prévoyez Python 3 et un environnement permettant d’ouvrir des fenêtres graphiques. Dans votre terminal, installez les deux paquets avec la commande suivante :

Créer un navigateur web en Python avec PyQt5, QWebEngineView et un serveur local de test
Créer un navigateur web en Python avec PyQt5, QWebEngineView et un serveur local de test

python -m pip install PyQt5 PyQtWebEngine

Selon votre installation, la commande Python peut s’appeler python3. Utilisez alors ce même nom pour installer les paquets et lancer le programme. Cette cohérence évite une cause fréquente de ModuleNotFoundError : installer une bibliothèque dans un interpréteur différent de celui qui exécute le fichier.

PyQt5 apporte les widgets et la gestion des événements. PyQtWebEngine fournit notamment QWebEngineView, importé depuis PyQt5.QtWebEngineWidgets. Puisque ce composant hérite de QWidget, il s’intègre dans les dispositions Qt ordinaires : QVBoxLayout, QHBoxLayout ou QGridLayout.

Si pip ne trouve aucune distribution compatible, vérifiez la version de Python et l’architecture de votre système. La disponibilité des paquets dépend de la plateforme ; changer uniquement le nom de l’import ne résoudra pas une incompatibilité.

Assembler un premier navigateur exécutable

Créez un fichier nommé navigateur.py et recopiez les lignes suivantes dans l’ordre, chacune sur sa propre ligne. Cet exemple reste volontairement sans classe personnalisée et sans bloc indenté pour rendre l’assemblage facile à suivre.

import sys

from PyQt5.QtCore import QUrl

from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QLineEdit, QPushButton, QMenuBar

from PyQt5.QtWebEngineWidgets import QWebEngineView

app = QApplication(sys.argv)

window = QMainWindow()

window.setWindowTitle("Navigateur Python")

window.resize(1100, 750)

central = QWidget()

layout = QVBoxLayout(central)

toolbar = QHBoxLayout()

address = QLineEdit()

address.setPlaceholderText("Adresse du site")

go = QPushButton("Aller")

back = QPushButton("Précédent")

forward = QPushButton("Suivant")

reload_button = QPushButton("Actualiser")

view = QWebEngineView()

toolbar.addWidget(back)

toolbar.addWidget(forward)

toolbar.addWidget(reload_button)

toolbar.addWidget(address, 1)

toolbar.addWidget(go)

layout.addLayout(toolbar)

layout.addWidget(view, 1)

window.setCentralWidget(central)

menu = QMenuBar(window)

window.setMenuBar(menu)

file_menu = menu.addMenu("Fichier")

quit_action = file_menu.addAction("Quitter")

quit_action.triggered.connect(window.close)

navigate = lambda: view.setUrl(QUrl.fromUserInput(address.text().strip())) if address.text().strip() else None

address.returnPressed.connect(navigate)

go.clicked.connect(navigate)

back.clicked.connect(view.back)

forward.clicked.connect(view.forward)

reload_button.clicked.connect(view.reload)

view.urlChanged.connect(lambda url: address.setText(url.toString()))

view.loadFinished.connect(lambda ok: window.statusBar().showMessage("Page chargée" if ok else "Échec du chargement"))

view.setHtml("<html><body><h2>Votre navigateur est prêt</h2><p>Saisissez une adresse pour commencer.</p></body></html>")

window.show()

sys.exit(app.exec_())

Lancez ensuite python navigateur.py. Une fenêtre apparaît avec une page d’accueil intégrée, quatre boutons, un champ de saisie et un menu Fichier. Saisissez une adresse complète commençant par https://, puis appuyez sur Entrée.

Comprendre la barre d’adresse et les événements Qt

Une seule action pour Entrée et le bouton Aller

QLineEdit collecte le texte ; QPushButton permet de le valider à la souris. Le signal returnPressed et le signal clicked appellent ici la même fonction navigate. Cette fonction retire les espaces superflus et transmet une QUrl à setUrl(), qui déclenche le chargement dans la vue web.

Documentation officielle de Qt WebEngine — Découvrez comment intégrer facilement du contenu web et un moteur de navigateur dans vos applications Qt.

QUrl.fromUserInput facilite l’interprétation d’une adresse saisie sans protocole. Pour un comportement prévisible, utilisez néanmoins une adresse explicite en HTTPS. On peut ajouter http:// lorsqu’un protocole manque, mais ce choix ne convient pas systématiquement : il faut distinguer les sites sécurisés des services locaux accessibles en HTTP.

Faire refléter la navigation dans l’interface

Le signal urlChanged actualise le champ lorsque l’utilisateur suit un lien ou revient en arrière. Les boutons Précédent, Suivant et Actualiser appellent directement les méthodes de QWebEngineView. QMenuBar accueille le menu de fermeture, tandis que app.exec_() maintient la boucle d’événements active pour recevoir les interactions.

Pensez à la barre d’adresse comme à un écho de la navigation, pas seulement comme à son point de départ. Une redirection peut conduire ailleurs que prévu : afficher l’adresse réellement chargée permet de le constater. Pour éviter une boucle de rétroaction, ne reliez pas chaque modification du texte à navigate ; gardez le chargement associé à une validation explicite.

Tester le résultat et reconnaître les limites du prototype

Validez d’abord les comportements essentiels : une adresse complète charge une page, Entrée et Aller produisent le même résultat, les liens mettent l’adresse à jour et le retour arrière retrouve la page précédente. Une saisie vide doit rester sans effet.

Pour un test local, placez un fichier index.html dans un dossier dédié, ouvrez un terminal dans ce dossier et lancez :

python -m http.server 8000 --bind 127.0.0.1

Saisissez ensuite http://127.0.0.1:8000 dans votre navigateur Python. L’écoute reste limitée à votre machine. Arrêtez le serveur avec Ctrl+C ; si le port est déjà utilisé, choisissez-en un autre. Ce serveur de test ne fournit par défaut ni chiffrement ni authentification.

En cas d’échec sur un site distant, vérifiez l’adresse, la connexion et l’accès depuis un navigateur habituel. Le message issu de loadFinished signale un problème général, sans en établir précisément la cause. Ne désactivez pas les contrôles de certificats pour contourner une erreur HTTPS.

Ce programme est un prototype, pas un remplacement immédiat de votre navigateur quotidien. Il ne propose pas de gestion explicite des téléchargements, des onglets, des favoris ou des permissions. Maintenez ses dépendances à jour et réservez cette première version à l’apprentissage ou à un usage maîtrisé. L’étape suivante consiste à organiser le code dans une classe, puis à ajouter ces fonctions progressivement.

À découvrir ensuite