Retour au blog
Guides
Sorin-Gabriel MaricaLast updated on Apr 22, 20269 min read

Le guide complet pour se lancer dans le web scraping avec Go

Le guide complet pour se lancer dans le web scraping avec Go

Le web scraping avec Go est un excellent moyen de créer un scraper rapide et puissant. En effet, GoLang est l'un des meilleurs langages de programmation pour la concurrence. Mais avant de nous lancer, je dois d'abord vous expliquer plus en détail ce qu'est le web scraping et en quoi il peut vous être utile.

Le web scraping est le processus qui consiste à extraire des données de sites web. Ce processus peut être effectué manuellement, mais cette approche n'est pas recommandée lorsqu'il s'agit de traiter de grandes quantités de données. Dans cet article, nous allons voir comment vous pouvez créer votre propre scraper web automatisé à partir de zéro avec Go.

Si vous débutez dans ce domaine, vous vous demandez peut-être quels sont les cas d'utilisation du web scraping. Voici une petite liste des plus courants :

  • Outils de comparaison de prix - Vous pouvez créer de nombreux outils à l'aide d'un scraper web. L'un des plus courants et des plus utiles est l'outil de comparaison de prix. Un tel outil récupérerait les prix d'un produit à partir de nombreuses sources et afficherait la meilleure offre possible.
  • Apprentissage automatique - Si vous souhaitez créer un modèle à l'aide de l'apprentissage automatique, vous aurez besoin d'un ensemble de données d'entraînement. Bien que vous puissiez parfois trouver des ensembles de données existants que vous pouvez utiliser, vous devrez souvent effectuer un travail supplémentaire et récupérer vous-même les données dont vous avez besoin.
  • Étude de marché - Un troisième cas d'utilisation consiste à extraire des informations sur Internet pour identifier vos concurrents et comprendre leurs activités. Vous pouvez ainsi rester au niveau de la concurrence, voire la devancer, en étant informé de toute nouvelle fonctionnalité qu'ils auraient pu ajouter.

De quoi aurez-vous besoin pour extraire des données avec Go ?

Avant de commencer, vous devrez pouvoir exécuter du code GoLang sur votre machine. Pour cela, il vous suffit d'installer Go, si ce n'est déjà fait. Vous trouverez plus de détails sur la manière d'installer Go et de vérifier si vous l'avez déjà installé ici.

Vous aurez également besoin d'un IDE ou d'un éditeur de texte de votre choix pour écrire le code. Je préfère utiliser Visual Studio Code, mais n'hésitez pas à utiliser celui qui vous convient le mieux.

Et c'est tout. Plutôt simple, non ? Passons maintenant au sujet principal de cet article : le web scraping avec Go.

Créer un scraper web avec Go

Pour créer notre scraper, nous avons d'abord besoin d'un objectif, c'est-à-dire d'un ensemble de données que nous voulons collecter à partir d'une source spécifique. J'ai donc choisi comme sujet pour notre scraper le scraping des téléchargements hebdomadaires des premiers paquets de npmjs.com qui utilisent le mot-clé « framework ». Vous pouvez les trouver sur cette page : https://www.npmjs.com/search?q=keywords:framework&page=0&ranking=optimal)

Inspectez le contenu de la page que vous souhaitez scraper

Pour bien effectuer le scraping, avant de commencer à extraire les données, vous devrez déterminer où elles se trouvent. Cela signifie que vous devrez créer les sélecteurs HTML pour interroger les données, en fonction de la structure HTML de la page.

Pour voir la structure HTML de la page, vous pouvez utiliser les outils de développement disponibles dans la plupart des navigateurs modernes. Dans Chrome, vous pouvez le faire en cliquant avec le bouton droit de la souris sur l’élément que vous souhaitez extraire, puis en cliquant sur « Inspecter la page ». Une fois que vous aurez fait cela, vous verrez quelque chose comme ceci :

À partir du code HTML que vous pouvez voir à droite (la fenêtre d'inspection), nous pouvons maintenant créer les sélecteurs que nous allons utiliser. Sur cette page, nous n'avons besoin que des URL de chacun des paquets.

En examinant le code HTML, nous constatons que les classes CSS utilisées par le site web sont générées par le code. Cela les rend peu fiables pour le scraping ; nous utiliserons donc les balises HTML à la place. Sur la page, nous voyons que les paquets se trouvent dans des balises <section> et que le lien vers le paquet se trouve dans la première div de la section.

Sachant cela, nous pouvons créer le sélecteur suivant pour extraire les liens de tous les paquets : section > div:first-child > div:first-child a. Avant de l'essayer dans le code, nous pouvons tester le sélecteur à partir des outils de développement du navigateur. Pour ce faire, rendez-vous dans l'onglet Console et exécutez document.querySelectorAll("{{ SELECTOR }}") :

En survolant chacun des éléments de la liste de nœuds renvoyés, nous pouvons voir qu'il s'agit exactement de ceux que nous recherchions, et nous pouvons donc utiliser ce sélecteur.

Scraping d'une page avec Go

Nous commençons enfin à créer le scraper ! Pour cela, vous devez d'abord créer un dossier dans lequel nous placerons tout notre code. Ensuite, vous devez ouvrir une fenêtre de terminal, soit depuis votre IDE, soit depuis votre système d'exploitation, et vous rendre dans notre dossier.

Pour ouvrir un terminal dans le dossier, dans Visual Studio Code, vous pouvez cliquer sur Terminal -> New Terminal (dans la barre supérieure).

Maintenant que notre terminal est ouvert, il est temps d'initialiser le projet. Pour ce faire, exécutez la commande suivante :

go mod init webscrapingapi.com/my-go-scraper

Cela créera dans votre dossier un fichier nommé go.mod avec le contenu suivant :

module webscrapingapi.com/my-go-scraper
go 1.19

Pour envoyer la requête à la page et extraire les sélecteurs du code HTML, nous utiliserons Colly, un paquet GoLang (consultez la documentation de Colly pour plus d'informations). Pour installer ce paquet, vous devez exécuter

go get github.com/gocolly/colly

Maintenant que tout est prêt, il ne nous reste plus qu'à créer notre fichier main.go et à écrire du code. Le code permettant d'extraire tous les liens de la première page des frameworks npmjs est le suivant :

package main

import (
    "fmt"
    "github.com/gocolly/colly"
)

func scrape() {
    c := colly.NewCollector()

    // Find and print all links
    c.OnHTML("section > div:first-child > div:first-child a", func(e *colly.HTMLElement) {
        fmt.Println(e.Attr("href"))
    })
    c.Visit("https://www.npmjs.com/search?q=keywords:framework&page=0&ranking=optimal")
}

func main() {
    scrape()
}

Si cela vous semble difficile à lire au premier abord, ne vous inquiétez pas, nous allons le décomposer dans les paragraphes suivants et vous l'expliquer. 

Chaque fichier GoLang doit commencer par le nom du package et les importations que Go utilisera. Dans ce cas, les deux packages que nous utilisons sont « fmt » pour afficher les liens que nous récupérons, et « Colly » (pour la récupération proprement dite).

Dans la partie suivante, nous avons créé la fonction scrape() qui se charge de récupérer les liens dont nous avons besoin. Pour ce faire, la fonction visite la première page et attend de trouver le sélecteur que nous avons défini. Lorsqu’un élément correspondant à ce sélecteur apparaît, elle affiche l’attribut href de cet élément.

La dernière partie est la fonction main, qui est la fonction appelée à chaque fois que nous exécutons un script Golang. Pour exécuter le code précédent, lancez go run main.go depuis votre terminal ; vous devriez obtenir le résultat suivant :

Comme vous pouvez le voir, l'attribut href contient des chemins relatifs vers les liens ; nous devrons donc le préfixer avec l'URL de npmjs.

Utilisez la concurrence de GoLang pour plus d'efficacité

L'une des fonctionnalités les plus intéressantes de GoLang est celle des GoRoutines. Les GoRoutines sont des threads simples et légers gérés par le runtime Go. Ce qui est formidable, c'est que Go peut nous aider à scraper de nombreuses URL en même temps à une vitesse fulgurante.

Auparavant, nous avons extrait les liens des 20 premiers paquets sous le mot-clé « framework » sur npmjs.com. Nous allons maintenant tenter de scraper tous ces liens en même temps et d'extraire le nombre de téléchargements hebdomadaires pour chacun d'entre eux. Pour ce faire, nous utiliserons les GoRoutines et les WaitGroups.

Voici le code final permettant d'extraire les téléchargements hebdomadaires à l'aide des goroutines :

package main

import (
    "fmt"
    "github.com/gocolly/colly"
    "sync"
)

func scrapeWeeklyDownloads(url string, wg *sync.WaitGroup) {
    defer wg.Done()

    c := colly.NewCollector()

    // Find and print the weekly downloads value
    c.OnHTML("main > div > div:last-child > div:not([class]) p", func(e *colly.HTMLElement) {
        fmt.Println(fmt.Sprintf("%s - %s", url, e.Text))
    })
    c.Visit(url)
}

func scrape() {
    c := colly.NewCollector()

    var wg sync.WaitGroup

    // Find and print all links
    c.OnHTML("section > div:first-child > div:first-child a", func(e *colly.HTMLElement) {
        wg.Add(1)
        go scrapeWeeklyDownloads(fmt.Sprintf("%s%s", "https://www.npmjs.com", e.Attr("href")), &wg)
    })
    c.Visit("https://www.npmjs.com/search?q=keywords:framework&page=0&ranking=optimal")

    wg.Wait()
}

func main() {
    scrape()
}

Voyons maintenant ce qui a été ajouté à notre code précédent. Vous remarquerez tout d’abord que nous avons importé un nouveau paquet appelé « sync ». Cela nous permettra d’utiliser les routines Go et d’attendre que les threads aient terminé avant d’arrêter l’exécution du programme.

L'élément suivant ajouté est la nouvelle fonction appelée « scrapeWeeklyDownloads ». Cette fonction accepte deux paramètres : l'URL du lien que nous allons scraper et un pointeur WaitGroup. Cette fonction se charge de visiter l'URL fournie et d'extraire les téléchargements hebdomadaires (en utilisant le sélecteur main > div > div:last-child > div:not([class]) p).

Les dernières modifications que vous remarquerez concernent la fonction scrape, où nous avons créé un WaitGroup à l'aide de var wg sync.WaitGroup. Ici, pour chaque lien de la page des paquets, nous avons utilisé wg.Add(1), puis créé une GoRoutine qui appelle la fonction scrapeWeeklyDownloads. À la fin de la fonction, l'instruction wg.Wait() fait en sorte que le code attende que toutes les GoRoutines aient fini de s'exécuter. 

Pour plus d'informations sur les WaitGroups, veuillez consulter cet exemple sur golang

Pourquoi les GoRoutines et les WaitGroups ?

En utilisant la concurrence dans Golang avec les GoRoutines et les WaitGroups, nous pouvons créer un scraper très rapide. L'exécution de l'exemple de code précédent renverra la page et les téléchargements hebdomadaires de chaque paquet. Cependant, comme nous utilisons le multithreading, l'ordre dans lequel ces informations s'afficheront est aléatoire (car les threads s'exécutent à des vitesses différentes).

Si vous exécutez le code sous Linux ou via le sous-système Linux de Windows (WSL), vous pouvez utiliser `time go run main.go` pour connaître le temps d'exécution de l'ensemble du script. Dans mon cas, le temps d'exécution est d'environ 5 à 6 secondes. C'est très rapide, étant donné que nous scrapons 21 pages (d'abord la page des paquets, puis les pages de chacun des paquets).

Autres obstacles

La plupart des scrapers comptent généralement sur une simple requête HTTP vers la page pour obtenir le contenu dont ils ont besoin. Cette solution est bonne, mais parfois les sites web affichent leurs informations via un rendu JavaScript. Cela signifie que le site web ne vous montrera d'abord qu'une partie de son contenu, le reste étant chargé dynamiquement via JavaScript.

Pour extraire ces pages, vous devrez utiliser ChromeDriver et contrôler un véritable navigateur Chrome. Bien qu'il existe certaines options pour le faire en Go, vous devrez effectuer des recherches supplémentaires sur ce sujet.

Même en tenant compte du rendu JavaScript, il reste encore quelques obstacles supplémentaires lors du scraping d'un site web. Certains sites web peuvent utiliser des détections anti-bot, des blocages d'IP ou des captchas pour empêcher les bots de scraper leur contenu. Pour continuer à scraper ces sites web, vous pouvez essayer d'utiliser quelques astuces de scraping web, comme ralentir votre scraper et le faire agir de manière plus humaine.

Mais si vous souhaitez conserver la rapidité de votre scraper et surmonter ces obstacles facilement, vous pouvez utiliser WebScrapingAPI. WebScrapingAPI est une API conçue pour vous aider dans le scraping en faisant tourner votre adresse IP et en contournant les détections anti-bot. Ainsi, vous pouvez continuer à profiter de la vitesse fulgurante offerte par GoLang et extraire vos données en un clin d’œil.

Conclusion sur le web scraping avec Go

Le Web Scraping est un moyen pratique et rapide d'extraire des données d'Internet, et il peut être utilisé pour de nombreux cas d'utilisation différents. Vous pouvez choisir d'extraire des données pour votre modèle d'apprentissage automatique ou de créer une application à partir de zéro en utilisant les données que vous avez extraites.

GoLang est l'une des meilleures solutions disponibles en matière de concurrence. En utilisant GoLang et Colly, vous pouvez créer un scraper rapide qui vous fournira vos données en un clin d'œil. Cela rend le web scraping avec Go très facile et efficace une fois que vous vous êtes habitué à la syntaxe de Go.

À propos de l'auteur
Sorin-Gabriel Marica, Développeur full-stack @ WebScrapingAPI
Sorin-Gabriel MaricaDéveloppeur full-stack

Sorin Marica est ingénieur Full Stack et DevOps chez WebScrapingAPI ; il développe des fonctionnalités pour les produits et assure la maintenance de l'infrastructure qui garantit le bon fonctionnement de la plateforme.

Commencez à créer

Prêt à faire évoluer votre système de collecte de données ?

Rejoignez plus de 2 000 entreprises qui utilisent WebScrapingAPI pour extraire des données Web à l'échelle de l'entreprise, sans aucun coût d'infrastructure.