NG NextGenMag
Tech

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

Éloïse Caradec 8 min de lecture
Creer un navigateur web en python : fenêtre Qt avec moteur Chromium

Pour créer un navigateur web en Python, le plus direct est d’associer PyQt5 pour l’interface et PyQtWebEngine pour afficher les pages. Vous obtenez une application de bureau avec une barre d’adresse, un bouton de navigation et un véritable moteur web. Vous ne créez pas un serveur : votre programme consulte les pages que des serveurs lui transmettent.

Ce que Python construit, et ce que le moteur web prend en charge

Dans ce projet, Python organise la fenêtre et les interactions : saisir une adresse, appuyer sur Entrée, revenir en arrière ou actualiser. Le composant QWebEngineView, importé depuis PyQt5.QtWebEngineWidgets, assure l’affichage des pages grâce à Qt WebEngine, fondé sur Chromium et son moteur de rendu Blink.

Quiz : créer un navigateur web en Python

Testez vos connaissances sur les composants et les étapes essentielles.

Réponses sélectionnées : 0 sur 7 Score : en attente
1. Quelle différence distingue principalement un navigateur web d’un serveur web ?
2. À quoi sert principalement PyQt5 dans ce projet ?
3. Quel est le rôle de PyQtWebEngine et de QWebEngineView ?
4. Quelle commande installe PyQt5 et PyQtWebEngine avec pip ?
5. Quel rôle joue QLineEdit dans un navigateur simple ?
6. Pourquoi utiliser QUrl avec l’adresse saisie avant de la charger ?
7. Comment tester le navigateur avec un serveur HTTP local simple ?

Vous n’avez donc pas à programmer l’interprétation du HTML, la mise en page CSS ou l’exécution JavaScript. En revanche, intégrer ce moteur ne suffit pas à reproduire toutes les fonctions d’un navigateur grand public.

ÉlémentRôleDans ce projet
Navigateur webDemande et affiche des ressources webVotre application PyQt5
Serveur webReçoit les requêtes et fournit des ressourcesUn serveur distant ou un serveur local
Page ou application webPrésente du contenu et des interactionsLe contenu chargé dans la vue

HTTP permet les échanges entre le navigateur et le serveur ; HTTPS y ajoute une protection par chiffrement. Le module Python http.server intervient du côté serveur, pas du côté de l’affichage. Il peut servir à tester votre navigateur, mais ne remplace pas QWebEngineView.

Préparer Python et installer les composants Qt

Utilisez Python 3 et, de préférence, un environnement virtuel propre au projet. Dans un terminal, exécutez la commande suivante pour le créer :

Schéma du fonctionnement pour créer un navigateur web en Python avec PyQt5 et QWebEngineView
Schéma du fonctionnement pour créer un navigateur web en Python avec PyQt5 et QWebEngineView

python -m venv .venv

Activez ensuite cet environnement avec .venv\Scripts\activate sous Windows, ou source .venv/bin/activate sous Linux et macOS. Selon votre installation, la commande Python peut s’appeler python3 plutôt que python.

Installez les deux dépendances dans cet environnement :

python -m pip install PyQt5 PyQtWebEngine

La commande pip install PyQtWebEngine installe le module web ; utiliser python -m pip permet surtout de cibler explicitement l’interpréteur qui exécutera votre fichier. C’est un bon réflexe pour éviter les erreurs liées à plusieurs installations de Python.

Vérifiez la compatibilité avant d’insister sur une installation qui échoue. Les paquets disponibles dépendent de la version de Python, du système et de l’architecture. Une version de Python très récente ne dispose pas nécessairement de paquets PyQt5 compatibles. Ne mélangez pas non plus des imports PyQt5 avec des exemples écrits pour PyQt6 ou PySide6.

Assembler un navigateur fonctionnel dans un seul fichier

Créez un fichier nommé navigateur.py. Recopiez les lignes ci-dessous dans leur ordre, en conservant l’indentation : quatre espaces dans la classe, puis huit dans ses méthodes. Cet exemple propose une barre d’adresse, un bouton Aller, les commandes précédent, suivant et actualiser, ainsi qu’un menu pour quitter.

import sys

from PyQt5.QtCore import QUrl

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

from PyQt5.QtWebEngineWidgets import QWebEngineView

class Navigateur(QMainWindow):

def __init__(self):

super().__init__()

self.setWindowTitle("Navigateur Python")

self.resize(1100, 750)

self.vue = QWebEngineView()

self.adresse = QLineEdit()

self.adresse.setPlaceholderText("Saisissez une adresse web")

barre = QHBoxLayout()

for texte, action in [("Précédent", self.vue.back), ("Suivant", self.vue.forward), ("Actualiser", self.vue.reload)]:

bouton = QPushButton(texte)

bouton.clicked.connect(action)

barre.addWidget(bouton)

barre.addWidget(self.adresse)

aller = QPushButton("Aller")

aller.clicked.connect(self.navigate)

barre.addWidget(aller)

disposition = QVBoxLayout()

disposition.addLayout(barre)

disposition.addWidget(self.vue)

conteneur = QWidget()

conteneur.setLayout(disposition)

self.setCentralWidget(conteneur)

self.adresse.returnPressed.connect(self.navigate)

self.vue.urlChanged.connect(self.actualiser_adresse)

self.vue.loadFinished.connect(self.afficher_etat)

menu = self.menuBar().addMenu("Fichier")

menu.addAction("Quitter", self.close)

self.vue.setHtml("<h2>Navigateur prêt</h2><p>Saisissez une adresse pour commencer.</p>")

def navigate(self):

texte = self.adresse.text().strip()

if not texte:

return

if "://" not in texte:

texte = "https://" + texte

url = QUrl(texte)

if url.isValid() and url.scheme() in ("http", "https") and url.host():

self.vue.setUrl(url)

else:

self.statusBar().showMessage("Adresse HTTP ou HTTPS non valide")

def actualiser_adresse(self, url):

self.adresse.setText(url.toString())

def afficher_etat(self, succes):

self.statusBar().showMessage("Page chargée" if succes else "Échec du chargement")

app = QApplication(sys.argv)

fenetre = Navigateur()

fenetre.show()

sys.exit(app.exec_())

Lancez ensuite python navigateur.py depuis le dossier contenant le fichier. La fenêtre doit afficher un message d’accueil avant toute connexion à un site.

Comprendre le trajet entre la saisie et la page affichée

QLineEdit recueille l’adresse. Le signal returnPressed et le clic sur QPushButton déclenchent la même méthode navigate(). Celle-ci retire les espaces périphériques, complète le protocole si nécessaire, puis transmet un objet QUrl à setUrl().

L’exemple privilégie HTTPS pour une adresse sans protocole. Pour un serveur local sans chiffrement, saisissez explicitement http://127.0.0.1:8000. Ajouter systématiquement http:// fonctionnerait sur certains services, mais n’est pas le choix par défaut retenu ici. La vérification de l’URL reste élémentaire : une adresse syntaxiquement acceptable ne garantit pas qu’un serveur existe.

QWebEngineView hérite de QWidget : il s’insère donc dans les dispositions Qt ordinaires. QHBoxLayout aligne les commandes horizontalement, tandis que QVBoxLayout place la vue sous cette barre. La méthode menuBar() de QMainWindow fournit la QMenuBar utilisée pour le menu Fichier. Enfin, app.exec_() lance la boucle d’événements qui maintient l’interface réactive.

Regardez la navigation à travers le prisme de trois adresses : celle saisie, celle demandée et celle finalement affichée. Elles peuvent différer après une redirection. Relier urlChanged à la barre d’adresse évite de montrer un ancien domaine alors que la page provient d’un autre. Cette synchronisation est donc un repère de confiance, pas seulement un détail esthétique.

Tester le résultat et fixer les limites du prototype

Commencez par une page publique simple, puis vérifiez les interactions une à une :

  • Saisir un domaine sans protocole et valider avec Entrée.
  • Charger une autre adresse avec le bouton Aller.
  • Suivre un lien et vérifier la mise à jour de l’adresse.
  • Tester Précédent, Suivant et Actualiser.
  • Essayer une adresse inexistante et observer le message d’échec.

Pour un test local, placez un fichier index.html dans un dossier réservé aux essais. Depuis ce dossier, lancez python -m http.server 8000 --bind 127.0.0.1, puis ouvrez http://127.0.0.1:8000 dans votre application. Arrêtez le serveur avec Ctrl+C. Ce serveur partage des fichiers sans authentification ni chiffrement par défaut ; l’écoute locale limite son exposition réseau.

Un message ModuleNotFoundError invite à vérifier l’environnement Python et ses dépendances. Une erreur Address already in use concerne le port du serveur local : choisissez un autre port et adaptez l’adresse. Pour une page distante inaccessible, contrôlez d’abord la connexion et l’URL, sans désactiver les protections de certificat.

Ce prototype est une base d’apprentissage, pas un navigateur sécurisé prêt à distribuer. Il reste notamment à concevoir les onglets, les favoris, la gestion des téléchargements et des permissions. Maintenez les dépendances à jour et réservez les usages sensibles à un navigateur régulièrement maintenu.

Éloïse Caradec
Retour en haut