Publié le 23 février 2026 SEO Technique

Def moteur de recherche : comprendre et optimiser la recherche avec Python et les moteurs web

Introduction : entre mot-clé def et moteurs de recherche

Le terme « def moteur de recherche » peut désigner à la fois la définition d’une fonction de recherche en Python et la compréhension du fonctionnement des moteurs de recherche web modernes. Pour rester compétitif en développement comme en SEO, il est essentiel de maîtriser ces deux dimensions : savoir coder une fonction de recherche efficace avec le mot-clé def, et comprendre comment les moteurs de recherche, dominés par Google avec près de 90 % de parts de marché dans le monde, traitent les requêtes des internautes. Dans cet article complet, nous allons expliquer en détail le rôle de def en Python, montrer comment concevoir une fonction de recherche, puis faire le lien avec les moteurs de recherche en ligne, leurs parts de marché et l’impact des nouveaux aperçus IA sur le trafic.

Concepts clés : définir une fonction Python pour un moteur de recherche

En Python, une fonction est une séquence d’instructions nommée qui réalise une tâche précise, comme rechercher un mot-clé dans une liste de pages ou filtrer des résultats. Le mot-clé def est utilisé pour définir cette fonction. Lorsque l’on parle de « def moteur de recherche », on imagine souvent une fonction qui va, à partir d’une requête utilisateur, explorer une collection de données (par exemple une liste d’articles) et retourner les résultats pertinents. Comprendre la syntaxe et la logique de def est donc la base pourécrire un mini moteur de recherche en Python, qu’il s’agisse d’une simple recherche textuelle ou d’un système plus avancé intégrant des scores de pertinence.

Voici leséléments essentiels du mot-clé def dans ce contexte :

  • Déclaration de fonction : Pour créer une fonction en Python, vous utilisez def suivi du nom de la fonction et des paramètres entre parenthèses, puis deux-points. Le corps de la fonction est indenté et contient les instructions à exécuter lors de l’appel.
  • Syntaxe générale : La forme standard est def nom_de_la_fonction(param1, param2): puis, sur les lignes suivantes indentées, les opérations à réaliser. Une fonction de recherche pourrait par exemple prendre une requête et une liste de documents.
  • Retour de valeur : Le mot-clé return permet de renvoyer un résultat au code qui a appelé la fonction, par exemple une liste de résultats triés par pertinence, un score ou un booléen indiquant si unélément aété trouvé.

Voici un exemple simple d’une fonction Python qui illustre le principe d’un mini moteur de recherche sur une liste de chaînes de caractères :

def moteur_de_recherche(requete, documents): """ Retourne la liste des documents contenant la requête. requete : chaîne recherchée (str) documents : liste de chaînes (list[str]) """ resultats = [] for doc in documents: if requete.lower in doc.lower: resultats.append(doc) return resultats

Cette fonction peut ensuiteêtre appelée avec une requête saisie par un utilisateur et une liste de contenus à explorer. Elle constitue la brique de base d’un moteur de recherche interne à une application ou à un site web, même si les moteurs de recherche professionnels sontévidemment beaucoup plus complexes et distribués à grandeéchelle.

Définir une fonction de recherche avancée en Python

Pour aller au-del à de la simple recherche de sous-chaîne, il est possible de créer avec def une fonction qui calcule un score de pertinence rudimentaire. Par exemple, on peut compter le nombre d’occurrences d’un mot-clé, prendre en compte plusieurs mots de la requête, ou encore appliquer des filtres. On parle alors de fonction de ranking. Cette logique se rapproche du fonctionnement d’un vrai moteur de recherche, où chaque page ou document se voit attribuer un score en fonction de sa correspondance avec la requête, de la popularité de la page et d’autres signaux.

Voici un exemple simplifié qui renvoie les documents triés par nombre d’occurrences d’un mot-clé :

def rechercher_avec_score(requete, documents): """ Retourne une liste de tuples (document, score) triés par score décroissant. """ resultats = [] terme = requete.lower for doc in documents: texte = doc.lower score = texte.count(terme) if score > 0: resultats.append((doc, score)) # Tri des résultats par score décroissant resultats_tries = sorted(resultats, key=lambda x: x[1], reverse=True) return resultats_tries

Une telle fonction repose toujours sur def, mais elle illustre déj à un principe essentiel des moteurs de recherche : chaque résultat estévalué et classé. Dans un environnement professionnel, ces fonctions s’intègrent dans des API, des microservices ou des applications web, et interagissent avec des index de recherche spécialisés comme Elasticsearch, OpenSearch ou Solr.

Bonnes pratiques pourécrire des fonctions Python liées à la recherche

Pourécrire du code de recherche efficace et maintenable en Python, il est essentiel d’adopter certaines bonnes pratiques lors de la définition des fonctions avec def. Tout d’abord, le nom de la fonction doitêtre clair : un nom comme rechercher_articles ou filtrer_resultats est bien plus parlant qu’un simple f ou fonction1. Ensuite, chaque fonction doit remplir une seule responsabilité : une fonction qui interroge un index ne devrait pas en même temps formater la réponse HTML ou interagir avec l’interface utilisateur. Cette séparation des responsabilités facilite les tests et la réutilisation.

  • Nommage significatif : Choisissez des noms explicites pour vos fonctions et vos paramètres (par exemple requete, index, limite_resultats). Cela améliore la lisibilité du code et réduit les risques d’erreur lors de la maintenance.
  • Responsabilité unique : Une fonction doit idéalement faire une seule chose. Par exemple, une fonction construire_index s’occupe de créer la structure de données qui stocke les documents, tandis qu’une fonction interroger_index se limite à renvoyer les documents pertinents pour une requête donnée.
  • Documentation claire : Utilisez des docstrings pour décrire le rôle de la fonction, ses paramètres, son type de retour etéventuellement les exceptions qu’elle peut lever. Cela est essentiel lorsqu’on collabore à plusieurs développeurs ou que le code doitêtre maintenu sur le long terme.
  • Tests unitaires : Créez des tests avec unittest ou pytest pour vérifier que vos fonctions de recherche retournent les bons résultats, même lorsque les données d’entrée sont imprévues, vides ou volumineuses.

En suivant ces principes, vous pouvez progressivement construire un moteur de recherche interne robuste, en Python, capable de traiter plusieurs milliers voire millions de documents. La clé reste la clarté des fonctions définies avec def et la qualité de leur découpage logique.

Outils et ressources utiles pour développer un moteur de recherche en Python

Pour optimiser votre processus de développement autour du mot-clé def et de la création de fonctions de recherche, il est recommandé d’utiliser des outils adaptés. Les environnements de développement intégrés comme PyCharm, VS Code ou même des solutions plus légères offrent une coloration syntaxique, un autocomplétion et un débogueur intégrés, qui facilitent l’écriture et l’analyse de votre code. Les linters tels que Pylint ou Flake8 vous aident à respecter les conventions de style Python (PEP 8) et à détecter les erreurs courantes avant même l’exécution.

  • Environnements de développement (IDE) : PyCharm, VS Code ou d’autres IDE facilitent le développement de fonctions de recherche grâce à l’autocomplétion, à la navigation rapide dans le code et aux intégrations de tests unitaires.
  • Linters et formatteurs : Pylint, Flake8, Black ou Ruff garantissent un code propre et homogène, ce qui est crucial dans des projets de recherche complexes où de multiples fonctions def interagissent entre elles.
  • Débogueurs : Les débogueurs intégrés permettent de poser des points d’arrêt à l’intérieur des fonctions de recherche, de suivre le parcours d’une requête pas à pas et de comprendre pourquoi certains résultats sont renvoyés ou non.
  • Bibliothèques spécialisées : Des solutions comme Whoosh (en pur Python), Elasticsearch via son client Python ou d’autres outils d’indexation permettent de combiner vos fonctions def avec des moteurs d’indexation performants.

En complément, de nombreuses ressources en ligne (documentation officielle de Python, forums spécialisés, communautés de développeurs) offrent des exemples concrets de fonctions de recherche, de structures d’index et de stratégies de classement. En les combinant intelligemment, vous pouvez concevoir un système qui se rapproche d’un moteur de recherche web tout en restant sous votre contrôle.

Panorama des moteurs de recherche web : parts de marché et usages

Pour bien saisir la portée de l’expression « def moteur de recherche », il est utile de replacer la notion de moteur de recherche dans le contexte du web. À l’échelle mondiale, Google domine très largement le marché, avec un peu plus de 90 % de parts de marché tous supports confondus en 2025. Sur mobile, sa domination est encore plus marquée, flirtant avec 95 % des recherches, tandis que sur ordinateur de bureau, sa part descend autour de 79 % mais reste largement majoritaire par rapport à ses concurrents.

En France, la situation est très proche de la moyenne mondiale. Tous supports confondus, Google concentre environ 90 % des recherches. Il est suivi par Bing, qui se situe légèrement au-dessus de 5 % du marché. Derrière, Yahoo! dépasse 1 % des recherches, tandis que des moteurs alternatifs comme Ecosia ou Yandex tournent autour de 1 % chacun. Ces chiffres confirment une situation de quasi-monopole, même si des moteurs alternatifs progressent lentement dans certains segments d’utilisateurs.

Au niveau mondial, les moteurs alternatifs comme Yandex (particulièrement présent en Russie), Baidu (très utilisé en Chine) ou DuckDuckGo (axé sur la protection de la vie privée) cumulent ensemble quelques pourcents du marché. Bing, de son côté, se situe généralement autour de 3à 4 % au niveau mondial, avec des variations selon les supports. Ces chiffres montrent que, lorsque vous parlez d’optimiser un « moteur de recherche », la compatibilité avec l’écosystème Google reste prioritaire pour la plupart des projets web, même si l’on ne doit pas négliger les alternatives pour toucher certains publics ou pays.

Fonctionnement général d’un moteur de recherche web

Un moteur de recherche web repose sur quatre grandesétapes : la collecte d’informations (crawl), l’indexation, le classement (ranking) et l’affichage des résultats. D’une certaine façon, chacune de cesétapes peutêtre modélisée en Python via des fonctions définies avec def : une fonction pour parcourir les pages, une fonction pour construire l’index, une fonction pour calculer la pertinence, et une autre pour formater les résultats. Sur Internet, ces fonctions sontévidemment distribuées sur des milliers de serveurs et optimisées à l’extrême pour gérer plusieurs milliards de pages.

  • Exploration (crawl) : Des robots parcourent en continu le web, suivent les liens et téléchargent les pages. On peut assimiler cela à une fonction qui effectue des requêtes HTTP, analyse le HTML et extrait les URLs.
  • Indexation : Le contenu des pages est analysé et stocké dans un immense index, souvent comparable à une base de données spécialisée. On peut imaginer une fonction indexer_document qui extrait les mots-clés et les stocke dans une structure adaptée.
  • Classement : Lorsqu’un utilisateur saisit une requête, le moteur calcule des scores de pertinence à l’aide de centaines de signaux (texte, liens, popularité, comportement utilisateur, etc.). C’est ici qu’interviennent des algorithmes complexes, pouvantêtre modélisés par des fonctions comme calculer_score.
  • Affichage : Les résultats sont enfin présentés dans une page de résultats (SERP), souvent enrichie de blocs supplémentaires (images, actualités, vidéos, cartes, aperçus IA). Une fonction Python pourrait, par exemple, construire la réponse JSON pour une API.

Cette analogie entre les moteurs web et les fonctions Python définies avec def montre que les mêmes principes de structuration, de modularité et de testabilité s’appliquent, que l’on travaille sur un petit projet ou sur un système à l’échelle mondiale.

Aperçus IA et impact sur le trafic des moteurs de recherche

Depuis 2024-2025, les grands moteurs de recherche, notamment Google, intègrent de plus en plus des aperçus IA (ou résumés générés par l’intelligence artificielle) directement dans la page de résultats. Ces blocs, affichés pour une partie des requêtes, proposent une synthèse de l’information, parfois accompagnée de liens. Cetteévolution a un impact concret sur le comportement des internautes et sur le trafic des sites. Pour certaines requêtes, le taux de clics sur les résultats organiques classiques peut chuter de manière marquée lorsque l’aperçu IA fournit déj à une réponse jugée suffisante par l’utilisateur.

Des analyses récentes montrent que ces nouveaux formats peuvent entraîner une baisse notable du taux de clics sur les liens traditionnels lorsque l’aperçu IA est présent, notamment sur les recherches effectuées depuis un ordinateur. AuxÉtats‑Unis, une part significative des requêtes desktop peut désormais afficher ce type de bloc IA, ce qui transforme profondément la stratégie de visibilité en ligne. Pour un développeur comme pour un spécialiste du référencement, comprendre cette dynamique permet d’anticiper les changements : concevoir des contenus de qualité, structurés, susceptibles d’être cités par ces aperçus, tout en continuant à proposer une valeur ajoutée qui incite au clic.

Parallèlement, la part de trafic générée par les plateformes d’IA pures (assistants conversationnels, outils d’IA générative) reste encore très faible par rapport au trafic global, même si elle connaît une croissance rapide. En France, la recherche organique traditionnelle pèse encore largement plus de la moitié du trafic web, ce qui confirme que les moteurs de recherche classiques restent l’axe principal pour acquérir des visiteurs, malgré la montée progressive de l’IA.

Relier Python, def et optimisation pour les moteurs de recherche

Le lien entre une fonction Python définie avec def et le monde du SEO peut sembler abstrait, mais il est en réalité très concret. De nombreux outils d’optimisation pour les moteurs de recherche sontécrits en Python : scripts pour analyser des logs, robots d’exploration interne, générateurs de rapports de positionnement, simulateurs de SERP, etc. Dans chacun de ces cas, la qualité du code, la clarté des fonctions et la rigueur des tests conditionnent la fiabilité des analyses obtenues. Une fonction malécrite peut mener à une mauvaise interprétation des performances d’un site dans les résultats de recherche.

Par exemple, vous pouvezécrire avec def une fonction qui extrait les balises </code> et les méta-descriptions d’une liste de pages, puis vérifier si elles contiennent les mots-clés principaux. Une autre fonction pourra calculer la fréquence des requêtes dans le contenu et signaler les sur-optimisations ou les manques. En automatisant ces tâches, vous gagnez du temps et pouvez vous concentrer sur l’amélioration concrète du contenu et de l’expérience utilisateur, deux piliers essentiels pourêtre bien positionné dans les moteurs de recherche dominants comme Google ou Bing. </p> <h2 id="foire-aux-questions-faq-sur-def-et-les-moteurs-de-recherche">Foire aux questions (FAQ) sur <code>def</code> et les moteurs de recherche</h2> <h3 id="pourquoi-est-il-important-d-utiliser-le-mot-cle-def-en-python">Pourquoi est-il important d’utiliser le mot-clé <code>def</code> en Python ?</h3> <p> Le mot-clé <code>def</code> est indispensable en Python car il permet de définir des fonctions réutilisables qui encapsulent une logique spécifique. En regroupant du code dans des fonctions bien nommées, vous rendez votre programme plus modulaire, plus lisible et plus facile à maintenir. Dans le cadre d’un moteur de recherche, cela signifie, par exemple, isoler la logique de filtrage, de calcul de score ou de formatage des résultats, ce qui facilite lesévolutions futures et les optimisations de performance. </p> <h3 id="comment-puis-je-ameliorer-la-structure-de-mes-fonctions-de-recherche">Comment puis-je améliorer la structure de mes fonctions de recherche ?</h3> <p> Pour améliorer la structure de vos fonctions de recherche en Python, commencez par découper vos tâches en sous-tâches distinctes : une fonction pour préparer les données, une pour effectuer la recherche, une autre pour trier et une dernière pour formater la réponse. Ajoutez des commentaires ou des docstrings pour clarifier le rôle de chaque fonction, et assurez-vous que chacune ne remplit qu’une seule responsabilité. Enfin, vérifiez régulièrement que le nom de vos fonctions reflète bien leur action (par exemple <code>rechercher_dans_index</code> ou <code>classer_resultats</code>), ce qui facilite la compréhension du code par d’autres développeurs. </p> <h3 id="quels-sont-les-meilleurs-outils-pour-tester-mes-fonctions-de-recherche">Quels sont les meilleurs outils pour tester mes fonctions de recherche ?</h3> <p> Pour tester vos fonctions Python, y compris celles qui implémentent un comportement de moteur de recherche, vous pouvez utiliser les modules de test intégrés comme <code>unittest</code>, ou des frameworks populaires comme <code>pytest</code>. Ces outils permettent d’écrire des tests unitaires qui vérifient que vos fonctions renvoient les bons résultats pour différentes requêtes, jeux de données et cas limites. Vous pouvez, par exemple, créer des jeux de documents de test et vérifier que votre fonction renvoie le bon nombre de résultats, dans le bon ordre, même lorsque la requête est vide ou ne correspond à rien. En combinant ces tests avec des linters et un environnement de développement adapté, vous obtenez un moteur de recherche interne plus fiable. </p> <h3 id="les-moteurs-de-recherche-traditionnels-vont-ils-disparaitre-avec-l-ia">Les moteurs de recherche traditionnels vont-ils disparaître avec l’IA ?</h3> <p> À court et moyen terme, les moteurs de recherche traditionnels ne disparaissent pas, même si l’IA transforme en profondeur la manière dont les résultats sont présentés. Les données récentes montrent que la recherche organique représente encore une part très importante du trafic web, notamment en France, et que les plateformes d’IA pures restent minoritaires en volume. Toutefois, l’intégration d’aperçus IA dans les résultats influence le comportement des utilisateurs et pousse les créateurs de contenu à s’adapter : produire des contenus plus structurés, répondre précisément aux questions des internautes et proposer une valeur ajoutée que ne fournit pas un simple résumé généré par l’IA. </p> <h3 id="comment-les-parts-de-marche-des-moteurs-de-recherche-influencent-elles-ma-strategie">Comment les parts de marché des moteurs de recherche influencent-elles ma stratégie ?</h3> <p> Les parts de marché montrent clairement que Google reste l’acteur dominant, avec environ 90 % des requêtes dans le monde et une position similaire en France. Cela signifie que l’optimisation pour Google reste prioritaire pour la majorité des projets. Cependant, la présence de concurrents comme Bing, Yahoo!, Yandex, Baidu, Ecosia ou DuckDuckGo justifie d’optimiser aussi pour des standards web ouverts (HTML bien structuré, performance, accessibilité), afin d’être correctement compris par ces moteurs. De plus, dans certains pays ou secteurs, un moteur alternatif peut avoir plus de poids, ce qui doitêtre pris en compte dans une stratégie internationale. </p> <h2 id="conclusion-tirer-parti-de-def-et-des-moteurs-de-recherche">Conclusion : tirer parti de <code>def</code> et des moteurs de recherche</h2> <p> Maîtriser le mot-clé <code>def</code> en Python et comprendre le fonctionnement des moteurs de recherche sont deux compétences complémentaires pour tout développeur ou spécialiste du web. D’un côté, <code>def</code> vous permet de créer des fonctions claires, réutilisables et testables, capables d’implémenter un mini moteur de recherche interne, d’analyser des données ou d’automatiser des tâches liées au SEO. De l’autre, la connaissance des parts de marché, des mécanismes de classement et de l’impact des aperçus IA vous aide à concevoir des contenus et des applications réellement visibles dans un paysage dominé par Google et ses concurrents. </p> <p> En combinant ces deux dimensions, vous pouvez non seulement optimiser vos fonctions de recherche en Python, mais aussi concevoir des outils et des sites mieux adaptés aux attentes des moteurs de recherche modernes. Prenez le temps de structurer vos fonctions avec <code>def</code>, de tester leur comportement, puis d’appliquer ces mêmes principes de clarté et de rigueur à vos contenus web : vous maximisez ainsi vos chances d’obtenir des résultats durables, tant sur le plan technique que sur celui de la visibilité en ligne. </p> </div> <!-- Articles similaires --> <div class="mt-12 pt-8 border-t border-gray-200"> <h2 class="text-2xl font-bold text-gray-900 mb-6 flex items-center gap-2"> <i class="fas fa-newspaper text-purple-600"></i> Articles similaires </h2> <div class="grid gap-4"> <a href="/blog/les-moteurs-de-recherche-comprendre-et-maitriser-l-optimisation-pour-les-moteurs-de-recherche/" class="block p-4 bg-white rounded-lg border border-gray-200 hover:border-purple-300 hover:shadow-md transition"> <span class="text-purple-600 font-semibold hover:text-purple-800">Les Moteurs de Recherche : Comprendre et Maîtriser l'Optimisation pour les Moteurs de Recherche</span> </a> <a href="/blog/definition-de-se-guide-complet-pour-comprendre-les-moteurs-de-recherche-et-le-seo/" class="block p-4 bg-white rounded-lg border border-gray-200 hover:border-purple-300 hover:shadow-md transition"> <span class="text-purple-600 font-semibold hover:text-purple-800">Définition de SE : Guide Complet pour Comprendre les Moteurs de Recherche et le SEO</span> </a> <a href="/blog/vitesse-et-performance-comprendre-et-optimiser-la-vitesse-de-chargement-d-une-page-web/" class="block p-4 bg-white rounded-lg border border-gray-200 hover:border-purple-300 hover:shadow-md transition"> <span class="text-purple-600 font-semibold hover:text-purple-800">Vitesse et performance : comprendre et optimiser la vitesse de chargement d’une page web</span> </a> </div> </div> <!-- CTA Section --> <div class="mt-12 pt-8 border-t border-gray-200"> <div class="bg-gradient-to-r from-purple-600 to-blue-600 rounded-xl p-8 text-center text-white"> <h3 class="text-2xl font-bold mb-4">Besoin d'aide avec votre SEO ?</h3> <p class="mb-6 text-purple-100">Notreéquipe d'experts peut vous aider à optimiser votre site e-commerce</p> <div class="flex flex-col sm:flex-row gap-4 justify-center"> <a href="/seo-ecommerce" class="bg-white text-purple-600 px-8 py-3 rounded-lg font-semibold hover:bg-purple-50 transition inline-block"> Découvrir nos services SEO </a> <a href="/#contact" class="bg-purple-800 text-white px-8 py-3 rounded-lg font-semibold hover:bg-purple-900 transition inline-block"> Nous contacter </a> </div> </div> </div> </article> <!-- Section Commentaires --> <div class="mt-12 max-w-4xl mx-auto bg-white rounded-2xl shadow-xl p-8 md:p-12"> <h2 class="text-3xl font-bold text-gray-900 mb-6 flex items-center gap-3"> <i class="fas fa-comments text-purple-600"></i> Commentaires </h2> <!-- Liste des commentaires approuvés --> <div id="comments-list" class="mb-8 space-y-6"> <!-- Les commentaires approuvés seront chargés ici via JavaScript --> </div> <!-- Formulaire de commentaire --> <div class="border-t border-gray-200 pt-8"> <h3 class="text-xl font-semibold text-gray-900 mb-4">Laisser un commentaire</h3> <form id="comment-form" class="space-y-4"> <input type="hidden" id="article-slug" value="def-moteur-de-recherche-comprendre-et-optimiser-la-recherche-avec-python-et-les-moteurs-web"> <div class="grid md:grid-cols-2 gap-4"> <div> <label for="comment-name" class="block text-sm font-medium text-gray-700 mb-2">Nom *</label> <input type="text" id="comment-name" name="name" required class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-600 focus:border-transparent"> </div> <div> <label for="comment-email" class="block text-sm font-medium text-gray-700 mb-2">Email *</label> <input type="email" id="comment-email" name="email" required class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-600 focus:border-transparent"> </div> </div> <div> <label for="comment-message" class="block text-sm font-medium text-gray-700 mb-2">Message *</label> <textarea id="comment-message" name="message" rows="5" required class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-600 focus:border-transparent"></textarea> </div> <div class="text-sm text-gray-600"> <i class="fas fa-info-circle text-purple-600"></i> Votre commentaire sera soumis à modération avant publication. </div> <button type="submit" class="bg-gradient-to-r from-purple-600 to-blue-600 text-white px-8 py-3 rounded-lg font-semibold hover:from-purple-700 hover:to-blue-700 transition inline-flex items-center gap-2"> <i class="fas fa-paper-plane"></i> Publier le commentaire </button> </form> <div id="comment-status" class="mt-4 hidden"></div> </div> </div> <!-- Navigation Articles --> <div class="mt-12 max-w-4xl mx-auto"> <a href="/blog" class="inline-flex items-center gap-2 text-purple-600 hover:text-purple-800 transition font-semibold"> <i class="fas fa-arrow-left"></i> Retour au blog </a> </div> </div> </section> <!-- Script pour les commentaires --> <script> const articleSlug = 'def-moteur-de-recherche-comprendre-et-optimiser-la-recherche-avec-python-et-les-moteurs-web'; // Charger les commentaires approuvés async function loadComments() { try { const response = await fetch(`/gestion-commentaires/get-comments.php?slug=${articleSlug}`); const data = await response.json(); const commentsList = document.getElementById('comments-list'); if (data.success && data.comments.length > 0) { commentsList.innerHTML = data.comments.map(comment => ` <div class="border-l-4 border-purple-600 pl-4 py-2"> <div class="flex items-center gap-2 mb-2"> <strong class="text-gray-900">${comment.name}</strong> <span class="text-sm text-gray-500">•</span> <span class="text-sm text-gray-500">${new Date(comment.date).toLocaleDateString('fr-FR')}</span> </div> <p class="text-gray-700">${comment.message}</p> </div> `).join(''); } else { commentsList.innerHTML = '<p class="text-gray-500 italic">Aucun commentaire pour le moment. Soyez le premier à commenter !</p>'; } } catch (error) { console.error('Erreur lors du chargement des commentaires:', error); } } // Gérer la soumission du formulaire document.getElementById('comment-form').addEventListener('submit', async function(e) { e.preventDefault(); const formData = { slug: articleSlug, name: document.getElementById('comment-name').value, email: document.getElementById('comment-email').value, message: document.getElementById('comment-message').value }; const submitBtn = this.querySelector('button[type="submit"]'); const originalText = submitBtn.innerHTML; submitBtn.disabled = true; submitBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Envoi en cours...'; try { const response = await fetch('/gestion-commentaires/submit-comment.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(formData) }); const result = await response.json(); const messageDiv = document.getElementById('comment-status'); if (result.success) { messageDiv.className = 'mt-4 p-4 bg-green-100 border border-green-400 text-green-700 rounded-lg'; messageDiv.textContent = 'Merci ! Votre commentaire aété soumis et sera publié après modération.'; messageDiv.classList.remove('hidden'); this.reset(); } else { messageDiv.className = 'mt-4 p-4 bg-red-100 border border-red-400 text-red-700 rounded-lg'; messageDiv.textContent = result.message || 'Une erreur est survenue. Veuillez réessayer.'; messageDiv.classList.remove('hidden'); } } catch (error) { const messageDiv = document.getElementById('comment-status'); messageDiv.className = 'mt-4 p-4 bg-red-100 border border-red-400 text-red-700 rounded-lg'; messageDiv.textContent = 'Erreur de connexion. Veuillez réessayer plus tard.'; messageDiv.classList.remove('hidden'); } finally { submitBtn.disabled = false; submitBtn.innerHTML = originalText; } }); // Charger les commentaires au chargement de la page loadComments(); </script> <footer class="bg-gray-950 text-gray-400 py-12"> <div class="container mx-auto px-6"> <div class="flex flex-col md:flex-row justify-between items-center"> <div class="mb-6 md:mb-0 flex items-start gap-4"> <img src="/images/logo.png" alt="Logo VRAIVEX" class="h-32 w-32 md:h-40 md:w-40 object-contain"> <div> <a href="#" class="text-2xl font-bold block"> <span class="gradient-text">VRAIVEX</span> </a> <p class="mt-2 text-sm">Automatisation, IA et SEO au service de la performance e-commerce</p> </div> </div> <div class="flex flex-col items-center md:items-end"> <div class="grid grid-cols-2 md:flex md:flex-wrap gap-3 md:space-x-6 mb-4 text-center md:text-right"> <a href="/#about" class="hover:text-white transition text-sm">À propos</a> <a href="/#services" class="hover:text-white transition text-sm">Services</a> <a href="/#prestations" class="hover:text-white transition text-sm">Prestations</a> <a href="/#bestsellers" class="hover:text-white transition text-sm">Best Sellers</a> <a href="/#realisations" class="hover:text-white transition text-sm">Réalisations</a> <a href="/#brands" class="hover:text-white transition text-sm">Nos Sites</a> <a href="/creation-site-ecommerce" class="hover:text-white transition text-sm">Création Sites</a> <a href="/seo-ecommerce" class="hover:text-white transition text-sm">SEO E-commerce</a> <a href="/partenaires" class="hover:text-white transition text-sm">Partenaires</a> <a href="/#contact" class="hover:text-white transition text-sm">Contact</a> </div> <p class="text-sm text-center md:text-right">© 2026 VRAIVEX. Tous droits réservés.</p> </div> </div> </div> </footer> <!-- Back to Top Button --> <button id="backToTop" class="fixed bottom-8 right-8 bg-gradient-to-r from-purple-600 to-blue-600 text-white p-4 rounded-full shadow-lg hover:shadow-xl transform hover:scale-110 transition-all duration-300 z-50 hidden"> <i class="fas fa-arrow-up text-xl"></i> </button> <script> // Header scroll effect window.addEventListener('scroll', function() { const header = document.getElementById('header'); if (window.scrollY > 100) { header.classList.add('header-scrolled'); } else { header.classList.remove('header-scrolled'); } }); // Smooth scrolling for anchor links document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function (e) { e.preventDefault(); document.querySelector(this.getAttribute('href')).scrollIntoView({ behavior: 'smooth' }); }); }); // Mobile menu toggle const mobileMenuButton = document.getElementById('mobileMenuButton'); const mobileMenu = document.getElementById('mobileMenu'); const menuIcon = document.getElementById('menuIcon'); if (mobileMenuButton && mobileMenu) { mobileMenuButton.addEventListener('click', function() { mobileMenu.classList.toggle('hidden'); // Toggle icon between bars and times if (mobileMenu.classList.contains('hidden')) { menuIcon.classList.remove('fa-times'); menuIcon.classList.add('fa-bars'); } else { menuIcon.classList.remove('fa-bars'); menuIcon.classList.add('fa-times'); } }); // Close menu when clicking on a link const mobileLinks = mobileMenu.querySelectorAll('a'); mobileLinks.forEach(link => { link.addEventListener('click', function() { mobileMenu.classList.add('hidden'); menuIcon.classList.remove('fa-times'); menuIcon.classList.add('fa-bars'); }); }); } // Brands Carousel const brandsCarousel = document.getElementById('brandsCarousel'); const brandsContainer = document.getElementById('brandsContainer'); const brandsPrevBtn = document.getElementById('brandsPrevBtn'); const brandsNextBtn = document.getElementById('brandsNextBtn'); const brandsPrevBtnMobile = document.getElementById('brandsPrevBtnMobile'); const brandsNextBtnMobile = document.getElementById('brandsNextBtnMobile'); if (brandsContainer && brandsCarousel) { let currentIndex = 0; const cards = brandsContainer.querySelectorAll('.brand-card'); const gap = 24; const cardsPerView = { mobile: 1, tablet: 2, desktop: 3, large: 4 }; function getCardsPerView() { const w = window.innerWidth; if (w >= 1280) return cardsPerView.large; if (w >= 1024) return cardsPerView.desktop; if (w >= 768) return cardsPerView.tablet; return cardsPerView.mobile; } function getCardWidth() { const cpv = getCardsPerView(); const cw = brandsCarousel.offsetWidth; return (cw - gap * (cpv - 1)) / cpv; } function updateCarousel() { const cpv = getCardsPerView(); const cardW = getCardWidth(); const maxIdx = Math.max(0, cards.length - cpv); currentIndex = Math.min(currentIndex, maxIdx); const offset = currentIndex * (cardW + gap); brandsContainer.style.transform = `translateX(-${offset}px)`; const atStart = currentIndex === 0; const atEnd = currentIndex >= maxIdx; [brandsPrevBtn, brandsPrevBtnMobile].forEach(function(btn) { if (btn) { btn.style.opacity = atStart ? '0.4' : '1'; btn.style.pointerEvents = atStart ? 'none' : 'auto'; } }); [brandsNextBtn, brandsNextBtnMobile].forEach(function(btn) { if (btn) { btn.style.opacity = atEnd ? '0.4' : '1'; btn.style.pointerEvents = atEnd ? 'none' : 'auto'; } }); if (document.getElementById('brandsCounter')) { document.getElementById('brandsCounter').textContent = (currentIndex + 1) + ' / ' + (maxIdx + 1); } } function nextSlide() { const cpv = getCardsPerView(); const maxIdx = Math.max(0, cards.length - cpv); if (currentIndex < maxIdx) { currentIndex++; updateCarousel(); } } function prevSlide() { if (currentIndex > 0) { currentIndex--; updateCarousel(); } } if (brandsNextBtn) brandsNextBtn.addEventListener('click', nextSlide); if (brandsPrevBtn) brandsPrevBtn.addEventListener('click', prevSlide); if (brandsNextBtnMobile) brandsNextBtnMobile.addEventListener('click', nextSlide); if (brandsPrevBtnMobile) brandsPrevBtnMobile.addEventListener('click', prevSlide); function setCardWidths() { const cardW = getCardWidth(); cards.forEach(function(card) { card.style.width = cardW + 'px'; card.style.minWidth = cardW + 'px'; card.style.flexShrink = '0'; }); } let touchStartX = 0; let touchEndX = 0; brandsCarousel.addEventListener('touchstart', function(e) { touchStartX = e.changedTouches[0].screenX; }, { passive: true }); brandsCarousel.addEventListener('touchend', function(e) { touchEndX = e.changedTouches[0].screenX; const diff = touchStartX - touchEndX; if (Math.abs(diff) > 50) { diff > 0 ? nextSlide() : prevSlide(); } }, { passive: true }); setCardWidths(); updateCarousel(); let resizeTimeout; window.addEventListener('resize', function() { clearTimeout(resizeTimeout); resizeTimeout = setTimeout(function() { setCardWidths(); currentIndex = 0; updateCarousel(); }, 250); }); } </script> <script> // Header scroll effect window.addEventListener('scroll', function() { const header = document.getElementById('header'); if (window.scrollY > 50) { header.classList.add('header-scrolled'); } else { header.classList.remove('header-scrolled'); } }); // Scroll animations const observerOptions = { threshold: 0.1, rootMargin: '0px 0px -50px 0px' }; const observer = new IntersectionObserver(function(entries) { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add('visible'); } }); }, observerOptions); // Observe all fade-in-up elements document.querySelectorAll('.fade-in-up').forEach(el => { observer.observe(el); }); // Smooth scroll for anchor links document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function (e) { e.preventDefault(); const target = document.querySelector(this.getAttribute('href')); if (target) { target.scrollIntoView({ behavior: 'smooth', block: 'start' }); } }); }); // Counter animation for stats function animateCounter(element, target, duration = 2000) { let start = 0; const increment = target / (duration / 16); const timer = setInterval(() => { start += increment; if (start >= target) { element.textContent = target + (element.textContent.includes('+') ? '+' : '') + (element.textContent.includes('K') ? 'K€' : ''); clearInterval(timer); } else { element.textContent = Math.floor(start) + (element.textContent.includes('+') ? '+' : '') + (element.textContent.includes('K') ? 'K€' : ''); } }, 16); } // Observe stats section const statsObserver = new IntersectionObserver(function(entries) { entries.forEach(entry => { if (entry.isIntersecting && !entry.target.classList.contains('animated')) { entry.target.classList.add('animated'); const statsCards = entry.target.querySelectorAll('.stats-card'); statsCards.forEach((card, index) => { setTimeout(() => { card.style.opacity = '0'; card.style.transform = 'translateY(20px)'; setTimeout(() => { card.style.transition = 'all 0.6s ease'; card.style.opacity = '1'; card.style.transform = 'translateY(0)'; }, 100); }, index * 100); }); } }); }, { threshold: 0.3 }); const statsSection = document.querySelector('section.bg-gradient-to-r'); if (statsSection) { statsObserver.observe(statsSection); } </script> <script> // Gestion du formulaire de contact const contactForm = document.getElementById('contact-form'); const formMessage = document.getElementById('form-message'); const submitBtn = document.getElementById('submit-btn'); if (contactForm) { contactForm.addEventListener('submit', async function(e) { e.preventDefault(); // Désactiver le bouton pendant l'envoi submitBtn.disabled = true; submitBtn.textContent = 'Envoi en cours...'; // Récupérer les données du formulaire const formData = new FormData(contactForm); try { // Vérifier que les données sont bien dans le FormData const formDataObj = { name: formData.get('name'), email: formData.get('email'), subject: formData.get('subject'), message: formData.get('message') }; console.log('Données du formulaire:', formDataObj); // Vérifier que tous les champs sont remplis if (!formDataObj.name || !formDataObj.email || !formDataObj.subject || !formDataObj.message) { formMessage.classList.remove('hidden'); formMessage.className = 'mb-6 p-4 rounded-lg bg-red-600 text-white'; formMessage.textContent = 'Veuillez remplir tous les champs du formulaire.'; submitBtn.disabled = false; submitBtn.textContent = 'Envoyer le message'; return; } // Essayer d'abord avec JSON (plus fiable) // Siça ne fonctionne pas, on essaiera avec FormData let response; try { // Méthode 1 : Envoyer en JSON (plus fiable selon les forums) response = await fetch('gestion-formulaire-contact/send-email-json.php', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(formDataObj) }); } catch (jsonError) { console.warn('Erreur avec JSON, essai avec FormData:', jsonError); // Méthode 2 : Fallback avec FormData response = await fetch('send-email.php', { method: 'POST', body: formData }); } // Lire le texte de la réponse d'abord pour déboguer const responseText = await response.text(); console.log('Réponse serveur:', responseText.substring(0, 500)); // Vérifier si la réponse est OK if (!response.ok) { // Essayer de parser le JSON d'erreur try { const errorResult = JSON.parse(responseText); // Afficher le message d'erreur du serveur directement à l'utilisateur formMessage.classList.remove('hidden'); formMessage.className = 'mb-6 p-4 rounded-lg bg-red-600 text-white'; formMessage.textContent = errorResult.message || `Erreur ${response.status}: ${response.statusText}`; submitBtn.disabled = false; submitBtn.textContent = 'Envoyer le message'; return; // Sortir de la fonction pour ne pas continuer } catch (e) { throw new Error(`Erreur HTTP ${response.status}: ${response.statusText}. Réponse: ${responseText.substring(0, 200)}`); } } // Vérifier si PHP n'est pas exécuté (le serveur renvoie le code PHP brut) if (responseText.trim().startsWith('<?php') || responseText.includes('<?php')) { console.error('ERREUR: PHP n\'est pas exécuté par le serveur. Le code PHP est renvoyé brut.'); console.error('Le serveur web n\'est pas configuré pour exécuter PHP.'); // Utiliser la solution de secours : sauvegarder dans localStorage const messageData = { name: formData.get('name'), email: formData.get('email'), subject: formData.get('subject'), message: formData.get('message'), timestamp: new Date().toISOString() }; // Sauvegarder dans localStorage comme solution de secours const savedMessages = JSON.parse(localStorage.getItem('vraivex_messages') || '[]'); savedMessages.push(messageData); localStorage.setItem('vraivex_messages', JSON.stringify(savedMessages)); // Afficher un message spécial formMessage.classList.remove('hidden'); formMessage.className = 'mb-6 p-4 rounded-lg bg-yellow-600 text-white'; formMessage.innerHTML = '⚠️ PHP n\'est pas configuré sur le serveur. Votre message aété sauvegardé localement. <br>Veuillez nous contacter directement à <strong>contact@vraivex.fr</strong> ou consulter les messages sauvegardés dans la console du navigateur.'; // Afficher les messages sauvegardés dans la console console.log('Messages sauvegardés localement:', savedMessages); console.log('Pour consulter les messages, tapez dans la console: JSON.parse(localStorage.getItem("vraivex_messages"))'); return; // Sortir de la fonction } // Essayer de parser le JSON let result; try { result = JSON.parse(responseText); } catch (parseError) { console.error('Erreur de parsing JSON:', parseError); console.error('Réponse reçue:', responseText.substring(0, 500)); throw new Error('Le serveur a renvoyé une réponse invalide. Vérifiez la console pour plus de détails.'); } // Afficher le message de résultat formMessage.classList.remove('hidden'); if (result.success) { formMessage.className = 'mb-6 p-4 rounded-lg bg-green-600 text-white'; formMessage.textContent = 'Message envoyé avec succès ! Nous vous répondrons dans les plus brefs délais.'; contactForm.reset(); } else { formMessage.className = 'mb-6 p-4 rounded-lg bg-red-600 text-white'; let errorMsg = result.message || 'Une erreur est survenue. Veuillez réessayer.'; // Afficher le message de debug en développement (à retirer en production) if (result.debug) { console.error('Erreur détaillée:', result.debug); } formMessage.textContent = errorMsg; } } catch (error) { formMessage.classList.remove('hidden'); formMessage.className = 'mb-6 p-4 rounded-lg bg-red-600 text-white'; // Message d'erreur plus détaillé pour le débogage let errorMsg = 'Une erreur est survenue lors de la communication avec le serveur. '; errorMsg += 'Veuillez réessayer plus tard ou nous contacter directement à contact@vraivex.fr'; // En mode développement, afficher plus de détails if (error.message) { console.error('Erreur détaillée:', error); console.error('Message:', error.message); console.error('Stack:', error.stack); } formMessage.textContent = errorMsg; } finally { // Réactiver le bouton submitBtn.disabled = false; submitBtn.textContent = 'Envoyer le message'; // Masquer le message après 5 secondes setTimeout(() => { formMessage.classList.add('hidden'); }, 5000); } }); } // Back to Top Button functionality const backToTopButton = document.getElementById('backToTop'); // Show/hide button based on scroll position window.addEventListener('scroll', () => { if (window.pageYOffset > 300) { backToTopButton.classList.remove('hidden'); } else { backToTopButton.classList.add('hidden'); } }); // Smooth scroll to top when clicked backToTopButton.addEventListener('click', () => { window.scrollTo({ top: 0, behavior: 'smooth' }); }); </script> </body> </html>