One place for hosting & domains

      utilisant

      Comment développer un site web Drupal 9 sur votre machine locale en utilisant Docker et DDEV


      L’auteur a choisi le Diversity in Tech Fund​​​​​ pour recevoir un don dans le cadre du programme Write for DOnations.

      Introduction

      DDEV est un outil open-source qui utilise Docker dans le but de construire des environnements de développement locaux pour de nombreux cadres PHP différents. Grâce à la puissance de la conteneurisation, DDEV peut grandement simplifier la façon dont vous travaillez sur des projets multiples qui utilisent plusieurs piles technologiques et plusieurs serveurs cloud. DDEV comprend des modèles pour WordPress, Laravel, Magento, TYPO3, Drupal, et plus encore.

      Drupal 9 a été publié le 3 juin 2020 pour le CMS Drupal. Connu pour sa facilité d’utilisation et sa vaste bibliothèque de modules et de thèmes, Drupal est un cadre PHP populaire pour la création et la maintenance de divers sites web et applications de toutes tailles.

      Dans ce tutoriel, vous allez commencer à développer un site web Drupal 9 sur votre machine locale en utilisant DDEV. Cela vous permettra de construire votre site web dans un premier temps, puis, lorsque vous serez prêt, de déployer votre projet sur un serveur de production.

      Conditions préalables

      Pour suivre ce tutoriel, vous aurez besoin de :

      Note : Il est possible de développer Drupal 9 en utilisant DDEV sur un serveur à distance, mais vous aurez besoin d’une solution pour accéder à localhost dans un navigateur web. La commande de DDEV ddev share fonctionne avec ngrok , qui crée un tunnel sécurisé vers votre serveur pour que vous et d’autres parties prenantes puissiez voir votre site de développement. Pour un usage personnel, vous pouvez également installer une interface graphique sur votre serveur à distance et accéder à votre site de développement via un navigateur web à l’intérieur de cette interface. Pour ce faire, vous pouvez suivre notre guide Comment installer et configurer VNC sur Ubuntu 20.04. Pour une solution GUI encore plus rapide, vous pouvez suivre notre guide sur la façon de configurer un bureau à distance avec X2Go sur Ubuntu 20.04.

      Étape 1 — Installer DDEV

      Au cours de cette étape, vous installerez DDEV sur votre machine locale. L’option 1 comprend des instructions pour macOS, tandis que l’option 2 fournit des instructions pour Linux. Ce tutoriel a été testé sur la version 1.15.0 de DDEV.

      Option 1 — Installation de DDEV sur macOS

      DDEV conseille aux utilisateurs de macOS d’installer leur outil en utilisant le gestionnaire de paquets Homebrew . Utilisez la commande brew suivante pour installer la dernière version stable :

      • brew tap drud/ddev && brew install drud/ddev/ddev

      Si vous préférez la version la plus récente, vous pouvez utiliser brew pour installer ddev-edge :

      • brew tap drud/ddev-edge && brew install drud/ddev-edge/ddev

      Si vous avez déjà une version de DDEV installée, ou si vous souhaitez mettre à jour votre version, arrêtez DDEV et utilisez brew pour mettre à jour votre installation :

      • ddev poweroff
      • brew upgrade ddev

      Une fois que vous avez installé ou mis à jour DDEV, exécutez  ddev version pour vérifier votre logiciel :

      Vous verrez un résultat similaire à ce qui suit :

      Output

      DDEV-Local version v1.15.0 commit v1.15.0 db drud/ddev-dbserver-mariadb-10.2:v1.15.0 dba phpmyadmin/phpmyadmin:5 ddev-ssh-agent drud/ddev-ssh-agent:v1.15.0 docker 19.03.8 docker-compose 1.25.5 os darwin router drud/ddev-router:v1.15.0 web drud/ddev-webserver:v1.15.0

      DDEV comprend un puissant CLI, ou interface de ligne de commande. Lancez ddev pour en savoir plus sur certaines commandes courantes :

      Vous verrez le résultat suivant :

      Output

      Create and maintain a local web development environment. Docs: https://ddev.readthedocs.io Support: https://ddev.readthedocs.io/en/stable/#support Usage: ddev [command] Available Commands: auth A collection of authentication commands composer Executes a composer command within the web container config Create or modify a ddev project configuration in the current directory debug A collection of debugging commands delete Remove all project information (including database) for an existing project describe Get a detailed description of a running ddev project. exec Execute a shell command in the container for a service. Uses the web service by default. export-db Dump a database to a file or to stdout help Help about any command hostname Manage your hostfile entries. import-db Import a sql file into the project. import-files Pull the uploaded files directory of an existing project to the default public upload directory of your project. list List projects logs Get the logs from your running services. pause uses 'docker stop' to pause/stop the containers belonging to a project. poweroff Completely stop all projects and containers pull Pull files and database using a configured provider plugin. restart Restart a project or several projects. restore-snapshot Restore a project's database to the provided snapshot version. sequelpro This command is not available since sequel pro.app is not installed share Share project on the internet via ngrok. snapshot Create a database snapshot for one or more projects. ssh Starts a shell session in the container for a service. Uses web service by default. start Start a ddev project. stop Stop and remove the containers of a project. Does not lose or harm anything unless you add --remove-data. version print ddev version and component versions Flags: -h, --help help for ddev -j, --json-output If true, user-oriented output will be in JSON format. -v, --version version for ddev Use "ddev [command] --help" for more information about a command.

      Pour plus d’informations sur l’utilisation de la CLI de DDEV, consultez la documentation officielle de DDEV.

      DDEV étant installée sur votre machine locale, vous êtes maintenant prêt(e) a installer Drupal 9 et à commencer à développer un site web.

      Option 2 — Installer DDEV sur Linux

      Sur un système d’exploitation Linux, vous pouvez installer DDEV en utilisant Homebrew pour Linux ou en utilisant le script d’installation officiel. Sur Ubuntu, commencez par mettre à jour votre liste de paquets dans le gestionnaire de paquets apt (vous pouvez utiliser apt dans Debian, sinon utilisez le gestionnaire de paquets équivalent associé à votre distribution Linux) :

      Installez maintenant quelques paquets pré-requis du dépôt officiel d’Ubuntu :

      • sudo apt install build-essential apt-transport-https ca-certificates software-properties-common curl

      Ces paquets vous permettront de télécharger le script d’installation de DDEV à partir de leur dépôt officiel GitHub.

      Maintenant, téléchargez le script :

      • curl -O https://raw.githubusercontent.com/drud/ddev/master/scripts/install_ddev.sh

      Avant d’exécuter le script, ouvrez-le dans nano ou votre éditeur de texte préféré et inspectez son contenu :

      nano install_ddev.sh
      

      Une fois que vous avez examiné le contenu du script et que vous êtes satisfait(e), enregistrez et fermez le fichier. Vous êtes maintenant prêt à exécuter le script d’installation.

      Utilisez la commande chmod pour rendre le script exécutable :

      Maintenant, lancez le script :

      Le processus d’installation peut vous demander de confirmer certains paramètres ou d’entrer votre mot de passe sudo. Une fois l’installation terminée, DDEV sera disponible sur votre système d’exploitation Linux.

      Exécutez la version ddev pour vérifier votre logiciel :

      Vous verrez un résultat similaire à ce qui suit :

      Output

      DDEV-Local version v1.15.0 commit v1.15.0 db drud/ddev-dbserver-mariadb-10.2:v1.15.0 dba phpmyadmin/phpmyadmin:5 ddev-ssh-agent drud/ddev-ssh-agent:v1.15.0 docker 19.03.8 docker-compose 1.25.5 os linux router drud/ddev-router:v1.15.0 web drud/ddev-webserver:v1.15.0

      DDEV est un puissant CLI, ou interface de ligne de commande. Exécutez ddev sans rien d’autre pour apprendre quelques commandes courantes :

      Vous verrez le résultat suivant :

      Output

      Create and maintain a local web development environment. Docs: https://ddev.readthedocs.io Support: https://ddev.readthedocs.io/en/stable/#support Usage: ddev [command] Available Commands: auth A collection of authentication commands composer Executes a composer command within the web container config Create or modify a ddev project configuration in the current directory debug A collection of debugging commands delete Remove all project information (including database) for an existing project describe Get a detailed description of a running ddev project. exec Execute a shell command in the container for a service. Uses the web service by default. export-db Dump a database to a file or to stdout help Help about any command hostname Manage your hostfile entries. import-db Import a sql file into the project. import-files Pull the uploaded files directory of an existing project to the default public upload directory of your project. list List projects logs Get the logs from your running services. pause uses 'docker stop' to pause/stop the containers belonging to a project. poweroff Completely stop all projects and containers pull Pull files and database using a configured provider plugin. restart Restart a project or several projects. restore-snapshot Restore a project's database to the provided snapshot version. sequelpro This command is not available since sequel pro.app is not installed share Share project on the internet via ngrok. snapshot Create a database snapshot for one or more projects. ssh Starts a shell session in the container for a service. Uses web service by default. start Start a ddev project. stop Stop and remove the containers of a project. Does not lose or harm anything unless you add --remove-data. version print ddev version and component versions Flags: -h, --help help for ddev -j, --json-output If true, user-oriented output will be in JSON format. -v, --version version for ddev Use "ddev [command] --help" for more information about a command.

      Pour plus d’informations sur l’utilisation du CLI de DDEV, vous pouvez consulter la documentation officielle de DDEV.

      DDEV étant installé sur votre machine locale, vous êtes maintenant prêt à déployer Drupal 9 et à commencer à développer un site web.

      Étape 2 — Déployer un nouveau site Drupal 9 en utilisant DDEV

      Avec l’exécution de DDEV, vous allez maintenant l’utiliser pour créer un système de fichiers spécifique à Drupal, installer Drupal 9, et ensuite lancer un projet de site web standard.

      Tout d’abord, vous allez créer un répertoire root du projet et ensuite vous déplacer à l’intérieur de celui-ci. Vous exécuterez toutes les commandes restantes à partir de cet emplacement. Ce tutoriel utilisera d9test , mais vous êtes libre de donner un autre nom à votre répertoire. Notez cependant que DDEV ne gère pas bien les noms avec trait d’union. Il est considéré comme une bonne pratique d’éviter les noms de répertoire comme my-project ou drupal-site-1.

      Créez le répertoire root de votre projet et naviguez à l’intérieur :

      DDEV excelle dans la création d’arborescences de répertoires qui correspondent à des plateformes CMS spécifiques. Utilisez la commande ddev config pour créer une structure de répertoire spécifique à Drupal 9 :

      • ddev config --project-type=drupal9 --docroot=web --create-docroot

      Vous verrez un résultat similaire à ce qui suit :

      Output

      Creating a new ddev project config in the current directory (/Users/sammy/d9test) Once completed, your configuration will be written to /Users/sammy/d9test/.ddev/config.yaml Created docroot at /Users/sammy/d9test/web You have specified a project type of drupal9 but no project of that type is found in /Users/sammy/d9test/web Ensuring write permissions for d9new No settings.php file exists, creating one Existing settings.php file includes settings.ddev.php Configuration complete. You may now run 'ddev start'.

      Parce que vous avez passé --project-type=drupal9 à votre commande ddev config, DDEV a créé plusieurs sous-répertoires et fichiers qui représentent l’organisation par défaut pour un site Drupal. L’arborescence de votre répertoire de projets ressemblera désormais à ceci :

      A Drupal 9 directory tree

      .
      ├── .ddev
      │   ├── .gitignore
      │   ├── config.yaml
      │   ├── db-build
      │   │   └── Dockerfile.example
      │   └── web-build
      │       └── Dockerfile.example
      └── web
          └── sites
              └── default
                  ├── .gitignore
                  ├── settings.ddev.php
                  └── settings.php
      
      6 directories, 7 files
      

      ddev/ sera le dossier principal pour la configuration de ddev. web/ sera le root documentaire de votre nouveau projet ; il contiendra plusieurs fichiers settings. spécifiques. Vous disposez maintenant de la structure initiale pour votre nouveau projet Drupal.

      Votrte prochaine étape consiste à initialiser votre plate-forme, qui permettra de construire les conteneurs et les configurations de réseau nécessaires.  DDEV se lie aux ports 80 et 443, donc si vous utilisez un serveur web comme Apache sur votre machine, ou tout autre chose qui utilise ces ports, arrêtez ces services avant de continuer.

      Utilisez la commande ddev start pour initialiser votre plate-forme :

      Cela permettra de construire tous les conteneurs basés sur Docker pour votre projet, qui comprennent un conteneur web, un conteneur de base de données et phpmyadmin. Une fois l’initialisation terminée, vous verrez un résultat comme celui-ci (votre numéro de port peut être différent) :

      Output

      ... Successfully started d9test Project can be reached at http://d9test.ddev.site http://127.0.0.1:32773

      Note : N’oubliez pas que DDEV démarre les conteneurs Docker en arrière-plan ici. Si vous voulez voir ces conteneurs ou vérifier qu’ils fonctionnent, vous pouvez toujours utiliser la commande docker ps :

      En plus des autres conteneurs que vous utilisez actuellement, vous trouverez quatre nouveaux conteneurs, chacun avec une image différente : php-myadmin, ddev-webserver, ddev-router, et ddev-dbserver-mariadb.

      ddev start a réussi à construire vos conteneurs et vous a donné une sortie avec deux URL. Bien que cette sortie indique que votre projet « can be reached at http://d9test.ddev.site and http://127.0.0.1:32773 », le fait de visiter ces URL maintenant entraînera une erreur. À partir de Drupal 8, le noyau de Drupal et les modules contrib fonctionnent comme des dépendances. Par conséquent, vous devez d’abord terminer l’installation de Drupal à l’aide de Composer, le gestionnaire de paquets pour les projets PHP, avant que tout ne se charge dans votre navigateur web.

      L’une des caractéristiques les plus utiles et les plus élégantes de DDEV est que vous pouvez passer les commandes de Composer par le CLI de DDEV et dans votre environnement conteneurisé. Cela signifie que vous pouvez séparer la configuration spécifique de votre machine de votre environnement de développement. Vous n’avez plus à gérer les différents problèmes de chemin de fichier, de dépendance et de version qui accompagnent généralement le développement local de PHP. De plus, vous pouvez rapidement changer de contexte entre plusieurs projets utilisant différents cadres et piles techniques avec un minimum d’effort.

      Utilisez la commande ddev composer pour télécharger drupal/recommended-project. Cela permettra de télécharger le noyau de Drupal, ses bibliothèques et d’autres ressources connexes, puis de créer un projet par défaut :

      • ddev composer create "drupal/recommended-project"

      Téléchargez maintenant un dernier composant appelé Drush, ou Drupal Shell. Ce tutoriel n’utilisera qu’une seule commande drush, et ce tutoriel fournit une alternative, mais drush est un CLI puissant pour le développement de Drupal qui peut améliorer votre efficacité.

      Utilisez ddev composer pour installer drush :

      • ddev composer require "drush/drush"

      Vous avez maintenant construit un projet Drupal 9 par défaut et installé drush. Vous allez maintenant visualiser votre projet dans un navigateur et configurer les paramètres de votre site web.

      Étape 3 — Configuration de votre projet Drupal 9

      Maintenant que vous avez installé Drupal 9, vous pouvez visiter votre nouveau projet dans votre navigateur. Pour ce faire, vous pouvez relancer ddev start et copier l’une des deux URL qu’il produit, ou vous pouvez utiliser la commande suivante, qui lancera automatiquement votre site dans une nouvelle fenêtre de navigateur :

      Vous y trouverez l’assistant d’installation standard de Drupal.

      Installateur Drupal 9 à partir du navigateur

      Vous avez ici deux possibilités. Vous pouvez utiliser cette interface utilisateur et suivre l’assistant tout au long de l’installation, ou vous pouvez retourner à votre terminal et passer une commande drush via ddev. Cette dernière option automatisera le processus d’installation et définira admin comme votre nom d’utilisateur et votre mot de passe.

      Option 1 — Utiliser l’assistant

      Retournez à l’assistant dans votre navigateur. Sous Choose language, sélectionnez une langue dans le menu déroulant et cliquez sur Save and continue. Sélectionnez maintenant un profil d’installation. Vous pouvez choisir entre Standard , Minimal , et Demo. Faites votre choix, puis cliquez sur Save and continue.  Drupal vérifiera automatiquement vos besoins, mettra en place une base de données et installera votre site. La dernière étape consiste à personnaliser quelques configurations. Ajoutez un nom de site et une adresse électronique de site qui se termine par votre domaine. Choisissez ensuite un nom d’utilisateur et un mot de passe. Choisissez un mot de passe fort et conservez vos informations d’identification dans un endroit sûr. Enfin, ajoutez une adresse électronique privée que vous vérifiez régulièrement, remplissez les paramètres régionaux, puis appuyez sur Save and continue.

      Message de bienvenue de Drupal 9 avec un avertissement sur les autorisations

      Votre nouveau site sera chargé avec un message de bienvenue.

      Option 2 — Utilisation de la ligne de commande

      Depuis le répertoire root de votre projet, lancez la commande ddev exec pour installer un site Drupal par défaut en utilisant drush :

      • ddev exec drush site:install --account-name=admin --account-pass=admin

      Votre site sera créé de la même manière que l’assistant, mais avec quelques configurations standard. Votre nom d’utilisateur et votre mot de passe seront admin.

      Lancez maintenant le site pour le visualiser dans votre navigateur :

      Vous êtes maintenant prêt à commencer à construire votre site web, mais il est considéré comme une bonne pratique de vérifier que vos autorisations sont correctes pour le répertoire /sites/web/default. Lorsque vous travaillez localement, ce n’est pas une préoccupation importante, mais si vous transférez ces autorisations à un serveur de production, elles poseront un risque de sécurité.

      Étape 4 — Vérifier vos autorisations

      Pendant l’installation de l’assistant, ou lors du premier chargement de votre page d’accueil, vous pouvez voir un avertissement concernant les paramètres des permissions dans votre répertoire /sites/web/default et un fichier à l’intérieur de ce répertoire : settings.php.

      Après l’exécution du script d’installation, Drupal essaiera de définir les permissions read et execute pour le répertoire web/sites/default, pour tous les groupes : il s’agit d’un paramètre de permissions 555. read only, ou 444. Si vous rencontrez cet avertissement, exécutez ces deux commandes `chmod` du répertoire root de votre projet. Tout manquement à cette obligation constitue un risque pour la sécurité :

      • chmod 555 web/sites/default
      • chmod 444 web/sites/default/settings.php

      Pour vérifier que vous avez les bonnes autorisations, exécutez la commande ls avec les boutons a , l , h et d :

      • ls -alhd web/sites/default web/sites/default/settings.php

      Vérifiez que vos autorisations correspondent à la sortie suivante :

      Output

      dr-xr-xr-x 8 sammy staff 256 Jul 21 12:56 web/sites/default -r--r--r-- 1 sammy staff 249 Jul 21 12:12 web/sites/default/settings.php

      Vous êtes maintenant prêt(e) à développer un site web Drupal 9 sur votre machine locale.

      Étape 5 — Créer votre premier article dans Drupal

      Pour tester certaines des fonctionnalités de Drupal, vous allez maintenant créer un message en utilisant l’interface utilisateur du web.

      Depuis la page initiale de votre site, cliquez sur le bouton Content dans le menu supérieur à gauche. Cliquez maintenant sur le bouton bleu add content. Une nouvelle page apparaîtra. Cliquez sur Article, et une autre page apparaîtra.

      Drupal 9 Créer une invite d'article  

      Ajoutez le titre et le contenu que vous souhaitez. Vous pouvez également ajouter une image, comme l’un des fonds d’écran de DigitalOcean . Lorsque vous êtes prêt, cliquez sur le bouton bleu save.

      Votre premier article apparaîtra sur votre site web.

      Création d'article par Drupal 9  

      Vous développez maintenant un site web Drupal 9 sur votre machine locale sans jamais interagir avec un serveur grâce à Docker et DDEV. Dans l’étape suivante, vous gérerez le conteneur DDEV afin d’adapter votre flux de travail.

      Étape 6 — Gérer le conteneur DDEV

      Lorsque vous avez terminé le développement de votre projet, ou lorsque vous souhaitez faire une pause, vous pouvez arrêter votre conteneur DDEV sans vous soucier de la perte de données. DDEV peut gérer un changement rapide de contexte parmi de nombreux projets ; c’est l’une de ses caractéristiques les plus utiles. Votre code et vos données sont toujours conservés dans le répertoire de votre projet, même après que vous ayez arrêté ou supprimé le conteneur DDEV.

      Pour libérer des ressources, vous pouvez arrêter DDEV à tout moment. Depuis le répertoire root de votre projet, exécutez la commande suivante :

      DDEV est disponible dans le monde entier, vous pouvez donc exécuter des commandes ddev depuis n’importe quel endroit, à condition de spécifier le projet DDEV :

      Vous pouvez également consulter tous vos projets en même temps en utilisant ddev list :

      DDEV comprend de nombreuses autres commandes utiles.

      Vous pouvez à tout moment relancer DDEV et continuer à vous développer localement.

      Conclusion

      Dans ce tutoriel, vous avez utilisé Docker et la puissance de la conteneurisation pour développer un site Drupal localement, avec l’aide de DDEV. DDEV s’intègre également bien avec de nombreux EDI et fournit un débogage PHP intégré pour Atom, PHPStorm et Visual Studio Code (vscode). Vous pouvez également en apprendre davantage sur la création d’environnements de développement pour Drupal avec DDEV ou sur le développement d’autres cadres PHP comme WordPress .



      Source link

      Comment moissonner un site web en utilisant Node.js et Puppeteer


      L’auteur a choisi le Free and Open Source Fund comme récipiendaire d’un don dans le cadre du programme Write for DOnations.

      Introduction

      Le moissonnage est une technique d’automatisation de la collecte des données depuis le web. Le processus déploie généralement un « collecteur » qui surfe automatiquement le web et moissonne les données des pages sélectionnées. Il existe de nombreuses raisons pour lesquelles vous pouvez vouloir extraire des données. En premier lieu, en éliminant le processus manuel de recueil de données, la collecte des données est beaucoup plus rapide. Vous pouvez également utiliser le moissonnage si vous souhaitez ou avez besoin de collecter des données mais que le site web ne dispose pas d’une API pour le faire.

      Au cours de ce tutoriel, vous allez créer une application de grattage web en utilisant Node.js et Puppeteer. Votre application deviendra de plus en plus complexe à mesure que vous progresserez. Vous allez tout d’abord coder votre application pour ouvrir Chromium et charger un site web spécial conçu comme un bac à sable de moissonnage : books.toscrape.com. Les deux prochaines étapes consisteront à extraire tous les livres sur une seule page (books.toscrape), puis tous les livres qui se trouvent sur plusieurs pages. Au cours des étapes restantes, vous allez filtrer votre moissonnage par catégorie de livres. Vous enregistrerez vos données en tant que fichier JSON.

      Avertissement : le moissonnage est éthiquement et légalement très complexe et en constante évolution. À ce titre, il est également très différent en fonction de votre région, de l’emplacement des données et du site web en question. Ce tutoriel moissonne un site web spécifique, books.toscrape.com, qui a été spécialement conçu pour tester des applications de moissonage. Le fait de remplacer ce domaine par un autre domaine ne relève pas de la portée de ce tutoriel.

      Conditions préalables

      Étape 1 — Configuration de l’application de Web Scraping

      Une fois Node.js installé, vous pouvez commencer à configurer votre application de moissonnage. Tout d’abord, vous allez créer un répertoire root de projet. Ensuite vous installerez les dépendances requises. Ce tutoriel ne nécessite qu’une seule dépendance que vous installerez en utilisant le gestionnaire de paquets npm par défaut de Node.js. npm est préinstallé avec Node.js, il est donc inutile de l’installer.

      Créez un dossier pour ce projet. Ensuite vous pouvez y entrer :

      • mkdir book-scraper
      • cd book-scraper

      Vous exécuterez toutes les commandes ultérieures depuis ce répertoire.

      Nous devons installer un paquet en utilisant npm ou le gestionnaire de paquets de nœuds. Tout d’abord, initialisez npm afin de créer un fichier packages.json qui permettra de gérer les dépendances et les métadonnées de votre projet.

      Initialisez npm pour votre projet :

      npm présentera une série d’invites. Vous pouvez appuyer sur ENTRÉE pour chaque invite ou ajouter des descriptions personnalisées. Veillez à bien appuyer sur ENTRÉE et à laisser les valeurs par défaut lorsqu’on vous y invite pour entry point: et test command:. Sinon, vous pouvez également faire transmettre le drapeau y sur npmnpm init -y—. Cela soumettra toutes les valeurs par défaut.

      Vous obtiendrez un résultat similaire à ceci :

      Output

      { "name": "sammy_scraper", "version": "1.0.0", "description": "a web scraper", "main": "index.js", "scripts": { "test": "echo "Error: no test specified" && exit 1" }, "keywords": [], "author": "sammy the shark", "license": "ISC" } Is this OK? (yes) yes

      Tapez yes et appuyez sur ENTER. npm pour enregistrer ce résultat en tant que votre fichier package.json.

      Maintenant, utilisez npm pour installer Puppeteer :

      • npm install --save puppeteer

      Cette commande installe à la fois Puppeteer et une version de Chromium validée par l’équipe de Puppeteer comme compatible avec son API.

      Sur les machines Linux, il se peut que Puppeteer nécessite des dépendances supplémentaires.

      Si vous utilisez Ubuntu 18.04, vérifiez la liste déroulante « Dépendances Debian » de la section « Chrome headless ne se lance pas sur UNIX » des documents de dépannage de Puppeteer. Vous pouvez utiliser la commande suivante pour trouver toutes les dépendances manquantes :

      Une fois npm, Puppeteer et toute dépendance supplémentaire installés, vous devrez procéder à une dernière configuration sur votre fichier package.json avant de commencer le codage. Au cours de ce tutoriel, vous allez lancer votre application depuis la ligne de commande avec  npm run start. Vous devez ajouter des informations sur ce script start dans package.json. Vous devez tout particulièrement ajouter une ligne sous la directive script liée à votre commande start.

      Ouvrez le fichier dans votre éditeur de texte préféré :

      Trouvez la section scripts et ajoutez les configurations suivantes. N’oubliez pas de placer une virgule à la fin de la ligne de script test. Dans le cas contraire, l’analyse de votre fichier ne se fera pas correctement.

      Output

      { . . . "scripts": { "test": "echo "Error: no test specified" && exit 1", "start": "node index.js" }, . . . "dependencies": { "puppeteer": "^5.2.1" } }

      Vous remarquerez également que, maintenant puppeteer apparaît sous dependencies près de la fin du fichier. Il ne sera pas nécessaire d’effectuer de révisions supplémentaires sur votre fichier package.json. Enregistrez vos modifications et fermez votre éditeur.

      Vous êtes maintenant prêt à commencer à coder votre application de moissonnage. Au cours de l’étape suivante, vous allez configurer une instance de navigateur et tester la fonctionnalité de base de votre application de moissonnage.

      Étape 2 — Configuration de l’instance de navigateur

      Lorsque vous ouvrez un navigateur traditionnel, vous pouvez cliquer sur des boutons, naviguer avec votre souris, utiliser votre clavier, ouvrir des outils de développement et bien plus encore. Avec un navigateur headless comme Chromium vous pouvez faire exactement ces mêmes choses, mais par programmation, sans interface utilisateur. Au cours de cette étape, vous allez configurer l’instance de navigateur de votre application de Web Scraping. Au lancement de votre application, elle ouvrira Chromium automatiquement et se rendra sur books.toscrape.com. Ces actions initiales constitueront la base de votre programme.

      Votre application de moissonnage aura besoin de quatre fichiers .js : browser.js, index,js, pageController.js, et pageScraper.js.  Au cours de cette étape, vous allez créer les quatre fichiers. Ensuite, à mesure que votre programme deviendra de plus en plus sophistiqué, vous devrez les mettre continuellement à jour. Commencez par browser.js. Ce fichier contiendra le script qui démarre votre navigateur.

      Depuis le répertoire root de votre projet, créez et ouvrez browser.js dans un éditeur de texte :

      Tout d’abord, vous aurez besoin de Puppeteer. Vous devrez ensuite créer une fonction async appelée startBrowser(). Cette fonction lancera le navigateur et renverra une instance de celui-ci. Ajoutez le code suivant :

      ./book-scraper/browser.js

      const puppeteer = require('puppeteer');
      
      async function startBrowser(){
          let browser;
          try {
              console.log("Opening the browser......");
              browser = await puppeteer.launch({
                  headless: false,
                  args: ["--disable-setuid-sandbox"],
                  'ignoreHTTPSErrors': true
              });
          } catch (err) {
              console.log("Could not create a browser instance => : ", err);
          }
          return browser;
      }
      
      module.exports = {
          startBrowser
      };
      

      Puppeteer dispose d’une méthode .launch() qui lance une instance d’un navigateur. Cette méthode renvoie une Promise. Vous devez donc vous assurer que la promesse est résolue en utilisant un bloc .then ou await.

      Utilisez await pour vous assurer que la promesse se résout, en enveloppant cette instance autour d’un bloc de code try-catch, puis en renvoyant une instance du navigateur.

      Notez que la méthode .launch() utilise un paramètre JSON avec plusieurs valeurs :

      • headlessfalse signifie que le navigateur s’exécutera avec une Interface qui vous permet de regarder votre script s’exécuter, tandis que true signifie que le navigateur s’exécutera en mode headless. Notez bien que, si vous souhaitez déployer votre application de moissonnage vers le cloud, reconfigurez headless sur true. La plupart des machines virtuelles sont headless et ne disposent pas d’une interface utilisateur. Elles peuvent donc exécuter le navigateur uniquement en mode headless. Puppeteer comprend également un mode headful mais il doit être uniquement utilisé pour réaliser des tests.
      • ignoreHTTPSErrorstrue vous permet de consulter des sites web qui ne sont pas hébergés sur un protocole HTTPS sécurisé et ignorent les erreurs liées à HTTPS.

      Enregistrez et fermez le fichier.

      Maintenant, créez votre deuxième fichier .js, index.js :

      Ici, vous aurez besoin de browser.js et de pageController.js. Ensuite, appelez la fonction startBrowser() et transmettez l’instance du navigateur créée à notre contrôleur de page, qui dirigera ses actions. Ajoutez le code suivant :

      ./book-scraper/index.js

      const browserObject = require('./browser');
      const scraperController = require('./pageController');
      
      //Start the browser and create a browser instance
      let browserInstance = browserObject.startBrowser();
      
      // Pass the browser instance to the scraper controller
      scraperController(browserInstance)
      

      Enregistrez et fermez le fichier.

      Créez votre troisième fichier .js, pageController.js :

      pageController.js contrôle votre processus de moissonnage. Il utilise l’instance du navigateur pour contrôler le fichier pageScraper.js sur lequel tous les scripts de moissonnage s’exécutent. Vous l’utiliserez éventuellement pour spécifier la catégorie de livres que vous souhaitez moissonner. Cependant, pour le moment, votre objectif est de pouvoir seulement ouvrir Chromium et naviguer vers une page web :

      ./book-scraper/pageController.js

      const pageScraper = require('./pageScraper');
      async function scrapeAll(browserInstance){
          let browser;
          try{
              browser = await browserInstance;
              await pageScraper.scraper(browser); 
      
          }
          catch(err){
              console.log("Could not resolve the browser instance => ", err);
          }
      }
      
      module.exports = (browserInstance) => scrapeAll(browserInstance)
      

      Ce code exporte une fonction qui prend l’instance de navigateur et la transmet à une fonction appelée scrapeAll(). À son tour, cette fonction transmet cette instance à pageScraper.scraper() en tant qu’argument qui l’utilise pour moissonner des pages.

      Enregistrez et fermez le fichier.

      Enfin, créez votre dernier fichier .js, pageScraper.js :

      Ici, vous allez créer un objet littéral avec une propriété url et une méthode scraper(). L’url est l’URL web de la page web que vous souhaitez moissonner. De son côté, la méthode scraper() contient le code qui exécutera votre moissonnage, même si à ce stade, elle se contente de se rendre sur une URL. Ajoutez le code suivant :

      ./book-scraper/pageScraper.js

      const scraperObject = {
          url: 'http://books.toscrape.com',
          async scraper(browser){
              let page = await browser.newPage();
              console.log(`Navigating to ${this.url}...`);
              await page.goto(this.url);
      
          }
      }
      
      module.exports = scraperObject;
      

      Puppeteer dispose d’une méthode newPage() qui crée une nouvelle instance de page dans le navigateur. Ces instances de page peuvent faire plusieurs choses. Avec notre méthode scraper(), vous avez créé une instance de page puis utilisé la méthode page.goto() pour naviguer vers la page d’accueil de books.toscrape.com.

      Enregistrez et fermez le fichier.

      Maintenant, la structure des fichiers de votre programme est achevée. Le premier niveau de l’arborescence de répertoire de votre projet ressemblera à ceci :

      Output

      . ├── browser.js ├── index.js ├── node_modules ├── package-lock.json ├── package.json ├── pageController.js └── pageScraper.js

      Maintenant, exécutez la commande npm run start et regardez votre application de moissonnage s’exécuter :

      Elle ouvrira automatiquement une instance de navigateur Chromium, ouvrira une nouvelle page dans le navigateur et naviguera vers books.toscrape.com.

      Au cours de cette étape, vous avez créé une application Puppeteer qui a ouvert Chromium et chargé la page d’accueil d’une librairie en ligne factice—books.toscrape.com. Au cours de l’étape suivante, vous allez moissonner les données de chaque livre qui se trouve sur cette page d’accueil.

      Étape 3 — Scraping des données à partir d’une seule page

      Avant d’ajouter plus de fonctionnalités à votre application de moissonnage, ouvrez votre navigateur web préféré et naviguez manuellement à la page d’accueil de books to scrape. Parcourez le site et faites-vous une idée sur la manière dont les données sont structurées.

      Image des sites web de books to scrape

      Vous trouverez une section de catégories à gauche et les livres affichés à droite. Lorsque vous cliquez sur un livre, le navigateur se dirige vers une nouvelle URL qui affiche les informations concernant ce livre spécifique.

      Au cours de cette étape, vous allez reproduire ce comportement, mais avec un code. Vous automatiserez l’activité de navigation sur le site web et la consommation de ses données.

      Tout d’abord, si vous inspectez le code source de la page d’accueil en utilisant les outils de développement de votre navigateur, vous remarquerez que la page répertorie les données de chaque livre sous une balise section. À l’intérieur de la balise section, chaque livre se trouve sous une balise list (li). Vous trouverez ici le lien vers la page dédiée du livre, le prix et le stock disponible.

      vue du code source de books.toscrape dans les outils de développement

      Vous effectuerez le scraping de ces URL de livres, appliquerez un filtre pour voir les livres en stock, naviguerez vers chaque page du livre et en réalisant le scraping de ses données.

      Rouvrez votre fichier pageScraper.js:

      Ajoutez le contenu en surbrillance suivant. Vous imbriquerez un autre bloc await à l’intérieur de await page.goto(this.url); :

      ./book-scraper/pageScraper.js

      
      const scraperObject = {
          url: 'http://books.toscrape.com',
          async scraper(browser){
              let page = await browser.newPage();
              console.log(`Navigating to ${this.url}...`);
              // Navigate to the selected page
              await page.goto(this.url);
              // Wait for the required DOM to be rendered
              await page.waitForSelector('.page_inner');
              // Get the link to all the required books
              let urls = await page.$$eval('section ol > li', links => {
                  // Make sure the book to be scraped is in stock
                  links = links.filter(link => link.querySelector('.instock.availability > i').textContent !== "In stock")
                  // Extract the links from the data
                  links = links.map(el => el.querySelector('h3 > a').href)
                  return links;
              });
              console.log(urls);
          }
      }
      
      module.exports = scraperObject;
      
      

      Dans ce bloc de code, vous avez appelé la méthode page.waitForSelector(). Cette méthode a attendu que le div qui contient toutes les informations liées à des livres soit rendu dans le DOM. Ensuite, vous avez appelé la méthode page.$$eval(). Cette méthode obtient l’élément URL avec le sélecteur section ol li (veillez à toujours renvoyer une chaîne ou un nombre à partir des méthodes page.$eval() et page.$$eval()).

      Chaque livre peut avoir deux statuts, il est soit En stock ou En rupture de stock. Vous allez extraire les livres qui sont En Stock. Étant donné que page.$$eval() renvoie un tableau de tous les éléments correspondants, filtrez ce tableau pour avoir la certitude de bien travailler qu’avec des livres en stock. Pour cela, recherchez et évaluez la catégorie .instock.availability. Ensuite, mappez la propriété href des liens du livre et renvoyez-la à partir de la méthode.

      Enregistrez et fermez le fichier.

      Ré-exécutez votre application :

      Le navigateur s’ouvrira, ira sur la page web, puis se fermera une fois la tâche achevée. Maintenant, vérifiez votre console. Elle contiendra toutes les URL moissonnées :

      Output

      > book-scraper@1.0.0 start /Users/sammy/book-scraper > node index.js Opening the browser...... Navigating to http://books.toscrape.com... [ 'http://books.toscrape.com/catalogue/a-light-in-the-attic_1000/index.html', 'http://books.toscrape.com/catalogue/tipping-the-velvet_999/index.html', 'http://books.toscrape.com/catalogue/soumission_998/index.html', 'http://books.toscrape.com/catalogue/sharp-objects_997/index.html', 'http://books.toscrape.com/catalogue/sapiens-a-brief-history-of-humankind_996/index.html', 'http://books.toscrape.com/catalogue/the-requiem-red_995/index.html', 'http://books.toscrape.com/catalogue/the-dirty-little-secrets-of-getting-your-dream-job_994/index.html', 'http://books.toscrape.com/catalogue/the-coming-woman-a-novel-based-on-the-life-of-the-infamous-feminist-victoria-woodhull_993/index.html', 'http://books.toscrape.com/catalogue/the-boys-in-the-boat-nine-americans-and-their-epic-quest-for-gold-at-the-1936-berlin-olympics_992/index.html', 'http://books.toscrape.com/catalogue/the-black-maria_991/index.html', 'http://books.toscrape.com/catalogue/starving-hearts-triangular-trade-trilogy-1_990/index.html', 'http://books.toscrape.com/catalogue/shakespeares-sonnets_989/index.html', 'http://books.toscrape.com/catalogue/set-me-free_988/index.html', 'http://books.toscrape.com/catalogue/scott-pilgrims-precious-little-life-scott-pilgrim-1_987/index.html', 'http://books.toscrape.com/catalogue/rip-it-up-and-start-again_986/index.html', 'http://books.toscrape.com/catalogue/our-band-could-be-your-life-scenes-from-the-american-indie-underground-1981-1991_985/index.html', 'http://books.toscrape.com/catalogue/olio_984/index.html', 'http://books.toscrape.com/catalogue/mesaerion-the-best-science-fiction-stories-1800-1849_983/index.html', 'http://books.toscrape.com/catalogue/libertarianism-for-beginners_982/index.html', 'http://books.toscrape.com/catalogue/its-only-the-himalayas_981/index.html' ]

      C’est un excellent début, mais en réalité, vous souhaitez extraire toutes les données pertinentes d’un livre spécifique, pas seulement son URL. Maintenant, utilisez ces URL pour ouvrir chaque page et moissonner le titre, l’auteur, le prix, la disponibilité, l’UPC, la description et l’URL d’image.

      Rouvrez pageScraper.js:

      Ajoutez le code suivant. Il parcourra chaque lien moissonné, ouvrira une nouvelle instance de page, puis récupéra les données pertinentes :

      ./book-scraper/pageScraper.js

      const scraperObject = {
          url: 'http://books.toscrape.com',
          async scraper(browser){
              let page = await browser.newPage();
              console.log(`Navigating to ${this.url}...`);
              // Navigate to the selected page
              await page.goto(this.url);
              // Wait for the required DOM to be rendered
              await page.waitForSelector('.page_inner');
              // Get the link to all the required books
              let urls = await page.$$eval('section ol > li', links => {
                  // Make sure the book to be scraped is in stock
                  links = links.filter(link => link.querySelector('.instock.availability > i').textContent !== "In stock")
                  // Extract the links from the data
                  links = links.map(el => el.querySelector('h3 > a').href)
                  return links;
              });
      
      
              // Loop through each of those links, open a new page instance and get the relevant data from them
              let pagePromise = (link) => new Promise(async(resolve, reject) => {
                  let dataObj = {};
                  let newPage = await browser.newPage();
                  await newPage.goto(link);
                  dataObj['bookTitle'] = await newPage.$eval('.product_main > h1', text => text.textContent);
                  dataObj['bookPrice'] = await newPage.$eval('.price_color', text => text.textContent);
                  dataObj['noAvailable'] = await newPage.$eval('.instock.availability', text => {
                      // Strip new line and tab spaces
                      text = text.textContent.replace(/(rnt|n|r|t)/gm, "");
                      // Get the number of stock available
                      let regexp = /^.*((.*)).*$/i;
                      let stockAvailable = regexp.exec(text)[1].split(' ')[0];
                      return stockAvailable;
                  });
                  dataObj['imageUrl'] = await newPage.$eval('#product_gallery img', img => img.src);
                  dataObj['bookDescription'] = await newPage.$eval('#product_description', div => div.nextSibling.nextSibling.textContent);
                  dataObj['upc'] = await newPage.$eval('.table.table-striped > tbody > tr > td', table => table.textContent);
                  resolve(dataObj);
                  await newPage.close();
              });
      
              for(link in urls){
                  let currentPageData = await pagePromise(urls);
                  // scrapedData.push(currentPageData);
                  console.log(currentPageData);
              }
      
          }
      }
      
      module.exports = scraperObject;
      

      Vous obtenez un tableau contenant toutes les URL. Parcourez ce tableau, ouvrez l’URL dans une nouvelle page, moissonnez les données de cette page, fermez-la et ouvrez une nouvelle page pour la prochaine URL du tableau. Notez que vous avez enveloppé ce code dans une promesse, car vous souhaitez avoir la possibilité d’attendre que chaque action de votre boucle s’achève. Par conséquent, chaque promesse ouvre une nouvelle URL et ne se résoudra pas tant que le programme n’aura pas moissonné toutes les données de l’URL. Ensuite, l’instance de la page se ferme.

      Avertissement : notez que vous avez attendu que la promesse s’exécute en utilisant une boucle for-in. Toute autre boucle sera suffisante. Évitez cependant d’itérer vos tableaux d’URL en utilisant une méthode d’itération de tableau comme forEach ou toute autre méthode qui utilise une fonction de rappel. En effet, la fonction de rappel devra tout d’abord passer par une file d’attente de rappels ainsi qu’une boucle d’événements, ce qui générera l’ouverture simultanée de plusieurs instances de page. Votre mémoire sera alors soumise à une plus forte contrainte.

      Regardez votre fonction pagePromise de plus près. Tout d’abord, votre application de moissonage a créé une nouvelle page pour chaque URL. Ensuite, vous avez utilisé la fonction page.$eval() pour cibler les sélecteurs des détails pertinents que vous avez voulu moissonner sur la nouvelle page. Certains textes contiennent des espaces, des onglets, de nouvelles lignes et d’autres caractères non alphanumériques que vous avez éliminés en utilisant une expression régulière. Ensuite, vous avez annexé la valeur de chaque partie de données moissonnée dans cette page à un objet et résolu l’objet en question.

      Enregistrez et fermez le fichier.

      Exécutez le script à nouveau :

      Le navigateur ouvre la page d’accueil puis chaque page du livre. Il enregistre ensuite les données moissonnées de chacune de ces pages. Le résultat suivant s’affichera sur votre console :

      Output

      Opening the browser...... Navigating to http://books.toscrape.com... { bookTitle: 'A Light in the Attic', bookPrice: '£51.77', noAvailable: '22', imageUrl: 'http://books.toscrape.com/media/cache/fe/72/fe72f0532301ec28892ae79a629a293c.jpg', bookDescription: "It's hard to imagine a world without A Light in the Attic. [...]', upc: 'a897fe39b1053632' } { bookTitle: 'Tipping the Velvet', bookPrice: '£53.74', noAvailable: '20', imageUrl: 'http://books.toscrape.com/media/cache/08/e9/08e94f3731d7d6b760dfbfbc02ca5c62.jpg', bookDescription: `"Erotic and absorbing...Written with starling power."--"The New York Times Book Review " Nan King, an oyster girl, is captivated by the music hall phenomenon Kitty Butler [...]`, upc: '90fa61229261140a' } { bookTitle: 'Soumission', bookPrice: '£50.10', noAvailable: '20', imageUrl: 'http://books.toscrape.com/media/cache/ee/cf/eecfe998905e455df12064dba399c075.jpg', bookDescription: 'Dans une France assez proche de la nôtre, [...]', upc: '6957f44c3847a760' } ...

      Au cours de cette étape, vous avez moissonné les données pertinentes pour chaque livre qui se trouve sur la page d’accueil de books.toscrape.com, mais vous pouvez ajouter beaucoup plus de fonctionnalités. Si, par exemple, chacune des pages des livres est paginée, comment pouvez-vous obtenir des livres depuis ces autres pages ? En outre, sur le côté gauche du site web, vous avez trouvé les catégories de livres. Que faire si vous ne voulez pas de tous les livres, mais seulement ceux d’un genre particulier ? Vous allez maintenant ajouter ces fonctionnalités.

      Étape 4 — Moissonnage de données à partir de plusieurs pages

      Sur les pages paginées de books.toscrape.com, un bouton next apparaît sous leur contenu, tandis que les pages qui ne sont pas paginées n’en ont pas.

      La présence de ce bouton vous permettra de déterminer si la page est paginée ou non. Étant donné que les données de chaque page ont la même structure et le même marquage, vous n’aurez pas à écrire une application de Scraping pour chaque page. Au contraire, vous pourrez utiliser la pratique récurrente.

      Tout d’abord, vous devez quelque peu modifier la structure de votre code pour pouvoir naviguer sur plusieurs pages de manière récurrente.

      Rouvrez pagescraper.js :

      Ajoutez une nouvelle fonction appelée scrapeCurrentPage() à votre méthode scraper(). Cette fonction contiendra l’intégralité du code qui moissonne les données à partir d’une page donnée. Ensuite, cliquez sur le bouton suivant s’il est présent. Ajoutez le code en surbrillance suivant :

      ./book-scraper/pageScraper.js scraper()

      const scraperObject = {
          url: 'http://books.toscrape.com',
          async scraper(browser){
              let page = await browser.newPage();
              console.log(`Navigating to ${this.url}...`);
              // Navigate to the selected page
              await page.goto(this.url);
              let scrapedData = [];
              // Wait for the required DOM to be rendered
              async function scrapeCurrentPage(){
                  await page.waitForSelector('.page_inner');
                  // Get the link to all the required books
                  let urls = await page.$$eval('section ol > li', links => {
                      // Make sure the book to be scraped is in stock
                      links = links.filter(link => link.querySelector('.instock.availability > i').textContent !== "In stock")
                      // Extract the links from the data
                      links = links.map(el => el.querySelector('h3 > a').href)
                      return links;
                  });
                  // Loop through each of those links, open a new page instance and get the relevant data from them
                  let pagePromise = (link) => new Promise(async(resolve, reject) => {
                      let dataObj = {};
                      let newPage = await browser.newPage();
                      await newPage.goto(link);
                      dataObj['bookTitle'] = await newPage.$eval('.product_main > h1', text => text.textContent);
                      dataObj['bookPrice'] = await newPage.$eval('.price_color', text => text.textContent);
                      dataObj['noAvailable'] = await newPage.$eval('.instock.availability', text => {
                          // Strip new line and tab spaces
                          text = text.textContent.replace(/(rnt|n|r|t)/gm, "");
                          // Get the number of stock available
                          let regexp = /^.*((.*)).*$/i;
                          let stockAvailable = regexp.exec(text)[1].split(' ')[0];
                          return stockAvailable;
                      });
                      dataObj['imageUrl'] = await newPage.$eval('#product_gallery img', img => img.src);
                      dataObj['bookDescription'] = await newPage.$eval('#product_description', div => div.nextSibling.nextSibling.textContent);
                      dataObj['upc'] = await newPage.$eval('.table.table-striped > tbody > tr > td', table => table.textContent);
                      resolve(dataObj);
                      await newPage.close();
                  });
      
                  for(link in urls){
                      let currentPageData = await pagePromise(urls);
                      scrapedData.push(currentPageData);
                      // console.log(currentPageData);
                  }
                  // When all the data on this page is done, click the next button and start the scraping of the next page
                  // You are going to check if this button exist first, so you know if there really is a next page.
                  let nextButtonExist = false;
                  try{
                      const nextButton = await page.$eval('.next > a', a => a.textContent);
                      nextButtonExist = true;
                  }
                  catch(err){
                      nextButtonExist = false;
                  }
                  if(nextButtonExist){
                      await page.click('.next > a');   
                      return scrapeCurrentPage(); // Call this function recursively
                  }
                  await page.close();
                  return scrapedData;
              }
              let data = await scrapeCurrentPage();
              console.log(data);
              return data;
          }
      }
      
      module.exports = scraperObject;
      
      

      Initialement, configurez la variable nextButtonExist sur false, ensuite vérifiez si le bouton existe. Si le bouton next existe, configurez nextButtonExists sur true. Vous pouvez ensuite cliquer sur le bouton next et appeler cette fonction de manière récurrente.

      Si nextButtonExists est configuré sur false, il renvoie le tableau scrapedData comme d’habitude.

      Enregistrez et fermez le fichier.

      Exécutez à nouveau votre script :

      Il est possible que cela vous prenne un certain temps. Après tout, votre application est en train d’effectuer le Scraping des données de plus de 800 livres. N’hésitez pas à fermer le navigateur ou à appuyer sur CTRL+C pour annuler le processus.

      Vous avez maintenant maximisé les capacités de votre application de moissonnage, mais vous avez créé un nouveau problème au cours du processus. En effet, plutôt que d’avoir trop peu de données, vous en avez trop. Au cours de l’étape suivante, vous allez affiner votre application afin de filtrer votre moissonnage par catégorie de livres.

      Étape 5 — Moissonnage des données par catégorie

      Pour moissonner des données par catégorie, vous devez modifier à la fois votre fichier pageScraper.js et votre fichier pageController.js.

      Ouvrez pageController.js dans un éditeur de texte :

      nano pageController.js
      

      Appelez l’application de moissonnage afin qu’elle moissonne uniquement les livres de voyage. Ajoutez le code suivant :

      ./book-scraper/pageController.js

      const pageScraper = require('./pageScraper');
      async function scrapeAll(browserInstance){
          let browser;
          try{
              browser = await browserInstance;
              let scrapedData = {};
              // Call the scraper for different set of books to be scraped
              scrapedData['Travel'] = await pageScraper.scraper(browser, 'Travel');
              await browser.close();
              console.log(scrapedData)
          }
          catch(err){
              console.log("Could not resolve the browser instance => ", err);
          }
      }
      module.exports = (browserInstance) => scrapeAll(browserInstance)
      

      Maintenant, vous êtes en train de transmettre deux paramètres dans votre méthode pageScraper.scraper(). Le deuxième paramètre correspond à la catégorie des livres que vous souhaitez moissonner, qui dans cet exemple est Travel. Mais votre fichier pageScraper.js ne reconnaît pas encore ce paramètre. Vous devez également ajuster ce fichier.

      Enregistrez et fermez le fichier.

      Ouvrez pageScraper.js:

      Ajoutez le code suivant. Il ajoutera votre paramètre de catégorie. Naviguez sur cette page de catégories, puis commencez à moissonner vos données à partir des résultats paginés :

      ./book-scraper/pageScraper.js

      const scraperObject = {
          url: 'http://books.toscrape.com',
          async scraper(browser, category){
              let page = await browser.newPage();
              console.log(`Navigating to ${this.url}...`);
              // Navigate to the selected page
              await page.goto(this.url);
              // Select the category of book to be displayed
              let selectedCategory = await page.$$eval('.side_categories > ul > li > ul > li > a', (links, _category) => {
      
                  // Search for the element that has the matching text
                  links = links.map(a => a.textContent.replace(/(rnt|n|r|t|^s|s$|Bs|sB)/gm, "") === _category ? a : null);
                  let link = links.filter(tx => tx !== null)[0];
                  return link.href;
              }, category);
              // Navigate to the selected category
              await page.goto(selectedCategory);
              let scrapedData = [];
              // Wait for the required DOM to be rendered
              async function scrapeCurrentPage(){
                  await page.waitForSelector('.page_inner');
                  // Get the link to all the required books
                  let urls = await page.$$eval('section ol > li', links => {
                      // Make sure the book to be scraped is in stock
                      links = links.filter(link => link.querySelector('.instock.availability > i').textContent !== "In stock")
                      // Extract the links from the data
                      links = links.map(el => el.querySelector('h3 > a').href)
                      return links;
                  });
                  // Loop through each of those links, open a new page instance and get the relevant data from them
                  let pagePromise = (link) => new Promise(async(resolve, reject) => {
                      let dataObj = {};
                      let newPage = await browser.newPage();
                      await newPage.goto(link);
                      dataObj['bookTitle'] = await newPage.$eval('.product_main > h1', text => text.textContent);
                      dataObj['bookPrice'] = await newPage.$eval('.price_color', text => text.textContent);
                      dataObj['noAvailable'] = await newPage.$eval('.instock.availability', text => {
                          // Strip new line and tab spaces
                          text = text.textContent.replace(/(rnt|n|r|t)/gm, "");
                          // Get the number of stock available
                          let regexp = /^.*((.*)).*$/i;
                          let stockAvailable = regexp.exec(text)[1].split(' ')[0];
                          return stockAvailable;
                      });
                      dataObj['imageUrl'] = await newPage.$eval('#product_gallery img', img => img.src);
                      dataObj['bookDescription'] = await newPage.$eval('#product_description', div => div.nextSibling.nextSibling.textContent);
                      dataObj['upc'] = await newPage.$eval('.table.table-striped > tbody > tr > td', table => table.textContent);
                      resolve(dataObj);
                      await newPage.close();
                  });
      
                  for(link in urls){
                      let currentPageData = await pagePromise(urls);
                      scrapedData.push(currentPageData);
                      // console.log(currentPageData);
                  }
                  // When all the data on this page is done, click the next button and start the scraping of the next page
                  // You are going to check if this button exist first, so you know if there really is a next page.
                  let nextButtonExist = false;
                  try{
                      const nextButton = await page.$eval('.next > a', a => a.textContent);
                      nextButtonExist = true;
                  }
                  catch(err){
                      nextButtonExist = false;
                  }
                  if(nextButtonExist){
                      await page.click('.next > a');   
                      return scrapeCurrentPage(); // Call this function recursively
                  }
                  await page.close();
                  return scrapedData;
              }
              let data = await scrapeCurrentPage();
              console.log(data);
              return data;
          }
      }
      
      module.exports = scraperObject;
      

      Ce bloc de code utilise la catégorie que vous avez transmise pour obtenir l’URL où se trouvent les livres de la catégorie en question.

      Le page.$$eval() peut prendre des arguments en transmettant l’argument en tant que troisième paramètre à la méthode $$eval(), et en le définissant comme le troisième paramètre dans le rappel de la manière suivante :

      example page.$$eval() function

      page.$$eval('selector', function(elem, args){
          // .......
      }, args)
      

      C’est ce que vous avez fait dans votre code. Vous avez passé la catégorie des livres que vous avez voulu moissonner, mappé toutes les catégories pour vérifier celles qui y correspondent et êtes revenu ensuite à l’URL de cette catégorie.

      Cette URL permet ensuite de naviguer vers la page qui affiche la catégorie des livres que vous souhaitez moissonner en utilisant la méthode page.goto(selectedCategory)

      Enregistrez et fermez le fichier.

      Exécutez votre application à nouveau. Vous remarquerez qu’elle se dirige vers la catégorie Travel, ouvre de manière récurrente les livres de cette catégorie, page par page, et journalise les résultats :

      Au cours de cette étape, vous avez moissonné des données sur plusieurs pages, puis celles d’une catégorie particulière. Au cours de l’étape finale, vous allez modifier votre script pour moissonner des données sur plusieurs catégories et enregistrer ensuite ces données moissonnées sur un fichier JSON composé de chaines.

      Étape 6 — Moissonnage des données de plusieurs catégories et sauvegarde des données en tant que JSON

      Au cours de cette dernière étape, vous allez moissonner les données de votre script sur autant de catégories que vous le souhaitez, puis changer votre manière de gérer les résultats. Plutôt que d’enregistrer les résultats, vous allez les sauvegarder dans un fichier structuré appelé data.json.

      Vous pouvez rapidement ajouter plus de catégories à extraire, ce qui nécessite uniquement une ligne supplémentaire par genre.

      Ouvrez pageController.js :

      Ajustez votre code pour inclure des catégories supplémentaires. L’exemple ci-dessous vous permet d’ajouter HistoricalFiction et Mystery à notre catégorie Travel existante :

      ./book-scraper/pageController.js

      const pageScraper = require('./pageScraper');
      async function scrapeAll(browserInstance){
          let browser;
          try{
              browser = await browserInstance;
              let scrapedData = {};
              // Call the scraper for different set of books to be scraped
              scrapedData['Travel'] = await pageScraper.scraper(browser, 'Travel');
              scrapedData['HistoricalFiction'] = await pageScraper.scraper(browser, 'Historical Fiction');
              scrapedData['Mystery'] = await pageScraper.scraper(browser, 'Mystery');
              await browser.close();
              console.log(scrapedData)
          }
          catch(err){
              console.log("Could not resolve the browser instance => ", err);
          }
      }
      
      module.exports = (browserInstance) => scrapeAll(browserInstance)
      

      Enregistrez et fermez le fichier.

      Exécutez le script à nouveau et regardez les données de ces trois catégories être moissonnées :

      Lorsque votre application de moissonnage est entièrement fonctionnelle, la dernière étape consiste à sauvegarder vos données sous un format plus pratique. Vous allez maintenant les stocker dans un fichier JSON en utilisant le module fs dans Node.js.

      Tout d’abord, rouvrez pageController.js :

      Ajoutez le code en surbrillance suivant :

      ./book-scraper/pageController.js

      const pageScraper = require('./pageScraper');
      const fs = require('fs');
      async function scrapeAll(browserInstance){
          let browser;
          try{
              browser = await browserInstance;
              let scrapedData = {};
              // Call the scraper for different set of books to be scraped
              scrapedData['Travel'] = await pageScraper.scraper(browser, 'Travel');
              scrapedData['HistoricalFiction'] = await pageScraper.scraper(browser, 'Historical Fiction');
              scrapedData['Mystery'] = await pageScraper.scraper(browser, 'Mystery');
              await browser.close();
              fs.writeFile("data.json", JSON.stringify(scrapedData), 'utf8', function(err) {
                  if(err) {
                      return console.log(err);
                  }
                  console.log("The data has been scraped and saved successfully! View it at './data.json'");
              });
          }
          catch(err){
              console.log("Could not resolve the browser instance => ", err);
          }
      }
      
      module.exports = (browserInstance) => scrapeAll(browserInstance)
      

      Tout d’abord, vous avez besoin du module fs de Node,js dans pageController.js. Vous pouvez ainsi enregistrer vos données en tant que fichier JSON. Ensuite, ajoutez un code de sorte que, une fois le Scraping achevé et le navigateur fermé, le programme créera un nouveau fichier appelé data.json. Notez que le contenu de data.json est stringified JSON. Par conséquent, lors de la lecture du contenu de data.json, analysez-le toujours en tant que JSON avant de réutiliser les données.

      Enregistrez et fermez le fichier.

      Vous avez maintenant développé une application de moissonnage qui moissonne les livres de plusieurs catégories et stocke ensuite les données que vous avez moissonnées dans un fichier JSON. Lorsque votre application devient plus complexe, vous pouvez stocker ces données moissonnées dans une base de données ou les utiliser avec une une API. Vous êtes ensuite libre d’utiliser ces données de la manière dont vous le souhaitez.

      Conclusion

      Vous avez développé un collecteur qui moissonne des données sur plusieurs pages de manière récurrente, puis les enregistre dans un fichier JSON. En résumé, vous avez appris à utiliser une nouvelle méthode d’automatiser la collecte des données à partir de sites web.

      Puppeteer dispose d’un grand nombre de fonctionnalités qui ne se trouvent pas dans ce tutoriel. Pour en savoir plus, consultez Utiliser Puppeteer pour un meilleur contrôle de Headless Chrome. Vous pouvez également consulter la documentation officielle de Puppeteer.



      Source link

      Comment héberger un site web en utilisant Cloudflare et Nginx sur Ubuntu 18.04


      L’auteur a choisi la Electronic Frontier Foundation comme récipiendaire d’un don dans le cadre du programme Write for DOnations.

      Introduction

      Cloudflare est un service qui se situe entre le visiteur et le serveur du propriétaire du site web, agissant comme un proxy inverse pour les sites web. Cloudflare fournit un Réseau de Diffusion de Contenu (CDN), ainsi que des services d’atténuation des DDoS et de serveurs de noms de domaine distribués.

      Nginx est un serveur web populaire qui héberge certains des sites les plus importants et les plus fréquentés d’Internet. Il est courant que des organisations desservent des sites web avec Nginx et utilisent Cloudflare comme fournisseur de CDN et de DNS.

      Dans ce tutoriel, vous allez sécuriser votre site web servi par Nginx avec un certificat Origin CA de Cloudflare et ensuite configurer Nginx pour utiliser des requêtes d’extraction authentifiées. Les avantages de cette configuration sont que vous bénéficiez du CDN et de la résolution DNS rapide de Cloudflare tout en vous assurant que toutes les connexions passent par Cloudflare. Cela empêche toute requête malveillante d’atteindre votre serveur.

      Conditions préalables

      Pour suivre ce tutoriel, vous aurez besoin des éléments suivants :

      Étape 1 – Génération d’un certificat Origin CA TLS

      Origin CA de Cloudflare vous permet de générer un certificat TLS gratuit signé par Cloudflare, à installer sur votre serveur Nginx. En utilisant le certificat TLS généré par Cloudflare, vous pouvez sécuriser la connexion entre les serveurs de Cloudflare et votre serveur Nginx.

      Pour générer un certificat avec Origin CA, connectez-vous à votre compte Cloudflare dans un navigateur web. Sélectionnez le domaine que vous souhaitez sécuriser et naviguez jusqu’à la section SSL/TLS de votre tableau de bord Cloudflare. De là, naviguez jusqu’à l’onglet Origin Server (Serveur d’origine) et cliquez sur le bouton Create Certificate (Créer un certificat)  :

      Option de création de certificat dans le tableau de bord de Cloudflare

      Laissez l’option par défaut Let Cloudflare generate a private key and a CSR (Laisser Cloudflare générer une clé privée et une RSE) sélectionnée.

      Options de l'interface graphique d'Origin CA

      Cliquez sur Next (Suivant) et vous verrez un dialogue avec le Origin Certificate (certificat d’origine) et la Private key (clé privée). Vous devez transférer à la fois le certificat d’origine et la clé privée de Cloudflare vers votre serveur. Pour des raisons de sécurité, les informations relatives à la clé privée ne s’afficheront plus. Copiez donc la clé sur votre serveur avant de cliquer sur Ok.

      Boîte de dialogue illustrant le certificat d'origine et la clé privée

      Nous utiliserons le répertoire /etc/ssl sur le serveur pour contenir les fichiers de certificat d’origine et de clé privée. Le dossier existe déjà sur le serveur.

      Tout d’abord, copiez le contenu du certificat d’origine affiché dans la boîte de dialogue de votre navigateur.

      Ensuite, sur votre serveur, ouvrez /etc/ssl/cert.pem dans votre éditeur de texte préféré :

      • sudo nano /etc/ssl/cert.pem

      Ajoutez le contenu du certificat dans le fichier. Ensuite, sauvegardez et quittez l’éditeur.

      Retournez ensuite à votre navigateur et copiez le contenu de la clé privée. Ouvrez le fichier /etc/ssl/key.pem pour le modifier :

      • sudo nano /etc/ssl/key.pem

      Collez la clé privée dans le fichier, enregistrez le fichier et quittez l’éditeur.

      Remarque : parfois, lorsque vous copiez le certificat et la clé à partir du tableau de bord Cloudflare et que vous les collez dans les fichiers correspondants sur le serveur, des lignes vierges sont insérées. Nginx considérera ces certificats et ces clés comme non valides, assurez-vous donc qu’il n’y a pas de lignes blanches dans vos fichiers.

      Attention : le certificat Origin AC de Cloudflare n’est fiable que sur Cloudflare et ne doit donc être utilisé que par les serveurs d’origine qui sont activement connectés à Cloudflare. Si, à un moment donné, vous mettez en pause ou désactivez Cloudflare, votre certificat d’AC d’origine affichera une erreur de certificat non fiable.

      Maintenant que vous avez copié les fichiers de clés et de certificats sur votre serveur, vous devez mettre à jour la configuration de Nginx pour les utiliser.

      Étape 2 – Installation du certificat d’origine AC dans Nginx

      Dans la section précédente, vous avez généré un certificat d’origine et une clé privée en utilisant le tableau de bord de Cloudflare et avez enregistré les fichiers sur votre serveur. Vous allez maintenant mettre à jour la configuration de Nginx pour votre site afin d’utiliser le certificat d’origine et la clé privée pour sécuriser la connexion entre les serveurs de Cloudflare et votre serveur.

      Tout d’abord, assurez-vous que UFW autorisera le trafic HTTPS. Activez Nginx Full, qui ouvrira à la fois le port 80 (HTTP) et le port 443 (HTTPS) :

      • sudo ufw allow 'Nginx Full'

      Relancez maintenant UFW :

      Enfin, vérifiez que vos nouvelles règles sont autorisées et que UFW est actif :

      Vous verrez un résultat similaire à ce qui suit :

      Output

      Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere Nginx Full ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) Nginx Full (v6) ALLOW Anywhere (v6)

      Vous êtes maintenant prêt à ajuster votre bloc serveur Nginx. Nginx crée un bloc serveur par défaut lors de l’installation. Supprimez-le s’il existe encore, car vous avez déjà configuré un bloc de serveur personnalisé pour votre domaine :

      • sudo rm /etc/nginx/sites-enabled/default

      Ensuite, ouvrez le fichier de configuration Nginx pour votre domaine :

      • sudo nano /etc/nginx/sites-available/your_domain

      Le dossier devrait ressembler à ceci :

      /etc/nginx/sites-available/your_domain

      server {
              listen 80;
              listen [::]:80;
      
              root /var/www/your_domain/html;
              index index.html index.htm index.nginx-debian.html;
      
              server_name your_domain www.your_domain;
      
              location / {
                      try_files $uri $uri/ =404;
              }
      }
      
      

      Nous allons modifier le fichier de configuration de Nginx pour faire ce qui suit :

      • Ecoutez sur le port 80 et redirigez toutes les requêtes pour qu’elles utilisent le protocole https.
      • Écoutez sur le port 443 et utilisez le certificat d’origine et la clé privée que vous avez ajoutés dans la section précédente.

      Modifiez le fichier de manière à ce qu’il ressemble à ce qui suit :

      /etc/nginx/sites-available/your_domain

      server {
          listen 80;
          listen [::]:80;
          server_name your_domain www.your_domain;
          return 302 https://$server_name$request_uri;
      }
      
      server {
      
          # SSL configuration
      
          listen 443 ssl http2;
          listen [::]:443 ssl http2;
          ssl        on;
          ssl_certificate         /etc/ssl/cert.pem;
          ssl_certificate_key     /etc/ssl/key.pem;
      
          server_name your_domain www.your_domain;
      
          root /var/www/your_domain/html;
          index index.html index.htm index.nginx-debian.html;
      
      
          location / {
                  try_files $uri $uri/ =404;
          }
      }
      

      Enregistrez le fichier et quittez l’éditeur.

      Ensuite, procédez à un test pour vous assurer qu’il n’y a aucune erreur de syntaxe dans aucun de vos fichiers Nginx :

      Si aucun problème n’a été trouvé, redémarrez Nginx pour permettre vos modifications :

      • sudo systemctl restart nginx

      Allez maintenant dans la section SSL/TLS du tableau de bord Cloudflare, naviguez jusqu’à l’onglet Overview (Vue d’ensemble), et changez le mode de cryptage SSL/TLS en mode Full (strict). Ceci informe Cloudflare de toujours crypter la connexion entre Cloudflare et votre serveur Nginx d’origine.

      Activez le mode SSL Full(strict) dans le tableau de bord de Cloudflare

      Visitez maintenant votre site web à l’adresse https://your_domain pour vérifier qu’il est correctement configuré. Vous verrez votre page d’accueil s’afficher et le navigateur vous indiquera que le site est sécurisé.

      Dans la section suivante, vous allez mettre en place des Authenticated Origin Pulls (Extractions à l’Origine Authentifiée) pour vérifier que votre serveur d’origine parle bien à Cloudflare et non à un autre serveur. Ce faisant, Nginx sera configuré pour n’accepter que les requêtes qui utilisent un certificat client valide de Cloudflare ; toutes les requêtes qui ne sont pas passées par Cloudflare seront abandonnées.

      Le certificat Origin CA aidera Cloudflare à vérifier qu’il parle au bon serveur d’origine. Cette étape utilisera l’authentification du client TLS pour vérifier que votre serveur Nginx d’origine parle à Cloudflare.

      Dans le cadre d’un handshake TLS authentifié par le client, les deux parties fournissent un certificat à vérifier. Le serveur d’origine est configuré pour n’accepter que les requêtes qui utilisent un certificat client Cloudflare valide. Les requêtes qui ne sont pas passées par Cloudflare seront abandonnées car elles n’auront pas le certificat de Cloudflare. Cela signifie que les pirates ne peuvent pas contourner les mesures de sécurité de Cloudflare, ni se connecter directement à votre serveur Nginx.

      Cloudflare présente des certificats signés par une AC avec le certificat suivant :

      -----BEGIN CERTIFICATE-----
      MIIGCjCCA/KgAwIBAgIIV5G6lVbCLmEwDQYJKoZIhvcNAQENBQAwgZAxCzAJBgNV
      BAYTAlVTMRkwFwYDVQQKExBDbG91ZEZsYXJlLCBJbmMuMRQwEgYDVQQLEwtPcmln
      aW4gUHVsbDEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzETMBEGA1UECBMKQ2FsaWZv
      cm5pYTEjMCEGA1UEAxMab3JpZ2luLXB1bGwuY2xvdWRmbGFyZS5uZXQwHhcNMTkx
      MDEwMTg0NTAwWhcNMjkxMTAxMTcwMDAwWjCBkDELMAkGA1UEBhMCVVMxGTAXBgNV
      BAoTEENsb3VkRmxhcmUsIEluYy4xFDASBgNVBAsTC09yaWdpbiBQdWxsMRYwFAYD
      VQQHEw1TYW4gRnJhbmNpc2NvMRMwEQYDVQQIEwpDYWxpZm9ybmlhMSMwIQYDVQQD
      ExpvcmlnaW4tcHVsbC5jbG91ZGZsYXJlLm5ldDCCAiIwDQYJKoZIhvcNAQEBBQAD
      ggIPADCCAgoCggIBAN2y2zojYfl0bKfhp0AJBFeV+jQqbCw3sHmvEPwLmqDLqynI
      42tZXR5y914ZB9ZrwbL/K5O46exd/LujJnV2b3dzcx5rtiQzso0xzljqbnbQT20e
      ihx/WrF4OkZKydZzsdaJsWAPuplDH5P7J82q3re88jQdgE5hqjqFZ3clCG7lxoBw
      hLaazm3NJJlUfzdk97ouRvnFGAuXd5cQVx8jYOOeU60sWqmMe4QHdOvpqB91bJoY
      QSKVFjUgHeTpN8tNpKJfb9LIn3pun3bC9NKNHtRKMNX3Kl/sAPq7q/AlndvA2Kw3
      Dkum2mHQUGdzVHqcOgea9BGjLK2h7SuX93zTWL02u799dr6Xkrad/WShHchfjjRn
      aL35niJUDr02YJtPgxWObsrfOU63B8juLUphW/4BOjjJyAG5l9j1//aUGEi/sEe5
      lqVv0P78QrxoxR+MMXiJwQab5FB8TG/ac6mRHgF9CmkX90uaRh+OC07XjTdfSKGR
      PpM9hB2ZhLol/nf8qmoLdoD5HvODZuKu2+muKeVHXgw2/A6wM7OwrinxZiyBk5Hh
      CvaADH7PZpU6z/zv5NU5HSvXiKtCzFuDu4/Zfi34RfHXeCUfHAb4KfNRXJwMsxUa
      +4ZpSAX2G6RnGU5meuXpU5/V+DQJp/e69XyyY6RXDoMywaEFlIlXBqjRRA2pAgMB
      AAGjZjBkMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgECMB0GA1Ud
      DgQWBBRDWUsraYuA4REzalfNVzjann3F6zAfBgNVHSMEGDAWgBRDWUsraYuA4REz
      alfNVzjann3F6zANBgkqhkiG9w0BAQ0FAAOCAgEAkQ+T9nqcSlAuW/90DeYmQOW1
      QhqOor5psBEGvxbNGV2hdLJY8h6QUq48BCevcMChg/L1CkznBNI40i3/6heDn3IS
      zVEwXKf34pPFCACWVMZxbQjkNRTiH8iRur9EsaNQ5oXCPJkhwg2+IFyoPAAYURoX
      VcI9SCDUa45clmYHJ/XYwV1icGVI8/9b2JUqklnOTa5tugwIUi5sTfipNcJXHhgz
      6BKYDl0/UP0lLKbsUETXeTGDiDpxZYIgbcFrRDDkHC6BSvdWVEiH5b9mH2BON60z
      0O0j8EEKTwi9jnafVtZQXP/D8yoVowdFDjXcKkOPF/1gIh9qrFR6GdoPVgB3SkLc
      5ulBqZaCHm563jsvWb/kXJnlFxW+1bsO9BDD6DweBcGdNurgmH625wBXksSdD7y/
      fakk8DagjbjKShYlPEFOAqEcliwjF45eabL0t27MJV61O/jHzHL3dknXeE4BDa2j
      bA+JbyJeUMtU7KMsxvx82RmhqBEJJDBCJ3scVptvhDMRrtqDBW5JShxoAOcpFQGm
      iYWicn46nPDjgTU0bX1ZPpTpryXbvciVL5RkVBuyX2ntcOLDPlZWgxZCBp96x07F
      AnOzKgZk4RzZPNAxCXERVxajn/FLcOhglVAKo5H0ac+AitlQ0ip55D2/mf8o72tM
      fVQ6VpyjEXdiIXWUq/o=
      -----END CERTIFICATE-----
      

      Vous pouvez également télécharger le certificat directement à partir de Cloudflare ici.

      Copiez ce certificat.

      Puis, créez le fichier /etc/ssl/cloudflare.crt pour y placer le certificat de Cloudflare  :

      • sudo nano /etc/ssl/cloudflare.crt

      Ajoutez le certificat au fichier. Ensuite, enregistrez le fichier et quittez l’éditeur.

      Mettez maintenant à jour votre configuration Nginx pour utiliser les Extractions d’Origine Authentifiée TLS. Ouvrez le fichier de configuration de votre domaine :

      • sudo nano /etc/nginx/sites-available/your_domain

      Ajoutez les directives ssl_client_certificate et ssl_verify_client, comme indiqué dans l’exemple suivant :

      /etc/nginx/sites-available/your_domain

      . . .
      
      server {
      
          # SSL configuration
      
          listen 443 ssl http2;
          listen [::]:443 ssl http2;
          ssl        on;
          ssl_certificate         /etc/ssl/cert.pem;
          ssl_certificate_key     /etc/ssl/key.pem;
          ssl_client_certificate /etc/ssl/cloudflare.crt;
          ssl_verify_client on;
      
          . . .
      

      Enregistrez le fichier et quittez l’éditeur.

      Ensuite, testez Nginx pour vous assurer qu’il n’y a pas d’erreurs de syntaxe dans votre configuration Nginx :

      Si aucun problème n’a été trouvé, redémarrez Nginx pour permettre vos modifications :

      • sudo systemctl restart nginx

      Enfin, pour activer les Extractions Authentifiées, ouvrez la section SSL/TLS dans le tableau de bord Cloudflare, naviguez jusqu’à l’onglet Origin Server (Serveur d’Origine) et cochez l’option Authenticated Origin Pulls.

      Activez les Extractions d'Origine Authentifiée

      Visitez maintenant votre site web à l’adresse https://your_domain pour vérifier qu’il est correctement configuré. Comme auparavant, vous verrez s’afficher votre page d’accueil.

      Pour vérifier que votre serveur n’accepte que les demandes signées par l’AC de Cloudflare, basculez l’option Authenticated Origin Pulls pour la désactiver, puis rechargez votre site web. Le message d’erreur suivant devrait apparaître :

      Message d'erreur

      Votre serveur d’origine génère une erreur si une requête n’est pas signée par l’AC de Cloudflare.

      Remarque : la plupart des navigateurs mettent les requêtes en cache. Pour voir le changement ci-dessus, vous pouvez donc utiliser le mode de navigation Incognito/Privé dans votre navigateur. Pour éviter que Cloudflare ne mette les requêtes en cache pendant que vous configurez votre site web, naviguez jusqu’à l’aperçu dans le tableau de bord Cloudflare et basculez en Development Mode (Mode Développement).

      Maintenant que vous savez qu’il fonctionne correctement, retournez à la section SSL/TLS du tableau de bord Cloudflare, naviguez jusqu’à l’onglet Origin Server (Serveur d’origine) et activez à nouveau l’option Authenticated Origin Pulls pour l’activer.

      Conclusion

      Dans ce tutoriel, vous avez sécurisé votre site web alimenté par Nginx en cryptant le trafic entre Cloudflare et le serveur Nginx à l’aide d’un certificat Origin CA de Cloudflare. Vous avez ensuite configuré des Authenticated Origin Pulls (Extractions d’Origine Authentifiée) sur le serveur Nginx pour vous assurer qu’il n’accepte que les requêtes des serveurs Cloudflare, empêchant ainsi toute autre personne de se connecter directement au serveur Nginx.



      Source link