Le web scraping est une technique puissante pour extraire des données de sites web, et Golang (Go) est un excellent langage pour cette tâche. Connu pour ses performances et son efficacité, Go peut gérer le web scraping avec facilité. Alors, comment extraire des données d'un site web avec Golang ? Ce guide vous guidera à travers le processus de scraping de pages web à l'aide de Golang, en couvrant les techniques et astuces associées.
Golang est-il adapté à la récupération de données sur le Web ?
Avant d'en savoir plus sur le scraping de données sur le web avec Golang, il est important de comprendre pourquoi choisir Golang pour le scraping de données sur le web et quels sont les avantages qu'il offre.
Golang est un choix judicieux pour le web scraping en raison de ses performances élevées, de son modèle de concurrence efficace et de sa bibliothèque standard robuste. Grâce à sa capacité à gérer plusieurs requêtes simultanément à l'aide de goroutines et à ses paquets intégrés pour les requêtes HTTP et l'analyse HTML, Go permet de récupérer efficacement de grands volumes de données. Sa simplicité et ses capacités de traitement des erreurs simplifient encore le processus de développement, tandis que des bibliothèques tierces comme Colly et Goquery offrent des fonctionnalités supplémentaires. Bien que moins répandu que Python pour le web scraping, les avantages de Go en font une option convaincante pour ceux qui sont familiers avec le langage.
Configuration de base pour récupérer des données Web avec Golang
Le scraping de données sur le web avec Go (Golang) consiste à effectuer des requêtes HTTP pour récupérer des pages web, puis à analyser le contenu HTML pour en extraire les informations souhaitées. Vous trouverez ci-dessous un guide étape par étape pour extraire des données du web à l'aide de Go :
-
-
Mise en place de l'environnement
Tout d'abord, assurez-vous que Go est installé sur votre système. Ni l'un ni l'autre n'a pu le télécharger à partir du site site officiel.
-
Installation des paquets nécessaires
Quelques paquets sont nécessaires pour faciliter les requêtes HTTP et l'analyse HTML. Les paquets les plus populaires sont net/http pour les requêtes HTTP et goquery pour l'analyse HTML.
Obtenez un paquet spécifique en exécutant la commande suivante :
aller chercher github.com/PuerkitoBio/goquery
L'écriture du grattoir
Voici une démonstration simple pour montrer comment récupérer des données d'un site web en utilisant Golang :
paquet principal import ( "fmt "log" "net/http "github.com/PuerkitoBio/goquery" ) func main() { // URL du site web à scraper url := "https://example.com" // Effectuer une requête HTTP GET res, err := http.Get(url) if err != nil { log.Fatal(err) } defer res.Body.Close() // Vérifier le code d'état de la réponse if res.StatusCode != 200 { log.Fatalf("Failed to fetch data : %d %s", res.StatusCode, res.Status) } // Analyse du HTML doc, err := goquery.NewDocumentFromReader(res.Body) if err != nil { log.Fatal(err) } // Recherche et impression des données doc.Find("h1").Each(func(index int, item *goquery.Selection) { heading := item.Text() fmt.Println(head) }) }
Effectuer des requêtes HTTP:
http.Get(url) envoie une requête HTTP GET à l'URL spécifiée.
res.Body.Close() garantit que le corps de la réponse est fermé après lecture.Analyse du code HTML:
goquery.NewDocumentFromReader(res.Body) analyse la réponse HTML et renvoie un objet goquery.Document.
Extraction des données:
doc.Find("h1").Each() recherche tous les éléments h1 dans le code HTML et les parcourt.
item.Text() extrait le contenu textuel de chaque élément h1. -
Faire fonctionner le grattoir
Enregistrez le code ci-dessus dans un fichier, par exemple, main.go, et exécutez-le en utilisant :
go run main.go
-
Autres considérations
Gestion des erreurs : Gérez toujours les erreurs de manière appropriée afin d'éviter que votre scraper ne se bloque de manière inattendue.
Respecter robots.txt: Vérifiez le fichier robots.txt du site web pour vous assurer que vous êtes autorisé à le scraper.
Limitation du débit : Mettre en place une limitation du débit pour éviter de submerger le serveur de demandes.
User-Agent : Définissez un en-tête User-Agent personnalisé pour identifier votre scraper, par exemple :
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("User-Agent", "Golang_Scraper/1.0")
client := &http.Client{}
res, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
// Analyse le code HTML comme précédemment
Techniques avancées pour récupérer des données Web avec Golang
Gestion de la pagination
De nombreux sites web utilisent la pagination pour répartir le contenu sur plusieurs pages. Pour récupérer toutes les données, vous devez gérer la pagination en envoyant des requêtes à chaque page de manière séquentielle.
Voici un exemple de gestion de la pagination :
paquet principal
import (
"fmt
"log"
"net/http
"strconv"
"github.com/PuerkitoBio/goquery"
)
func main() {
baseURL := "https://example.com/page/"
page := 1
for {
url := baseURL + strconv.Itoa(page)
res, err := http.Get(url)
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
if res.StatusCode != 200 {
log.Println("Plus de pages à récupérer, arrêt.")
break
}
doc, err := goquery.NewDocumentFromReader(res.Body)
if err != nil {
log.Fatal(err)
}
doc.Find(".item").Each(func(index int, item *goquery.Selection) {
title := item.Find(".title").Text()
fmt.Println(title)
})
page++
}
}
Gestion du contenu rendu par JavaScript
Certains sites web utilisent JavaScript pour rendre le contenu dynamique. Go ne dispose pas d'un moyen intégré d'exécuter JavaScript, mais vous pouvez utiliser un fichier navigateur sans tête comme Chromedp.
go get -u github.com/chromedp/chromedp
Exemple d'utilisation de Chromedp pour récupérer du contenu rendu en JavaScript :
paquet principal
import (
"contexte
"fmt"
"log"
"github.com/chromedp/chromedp"
)
func main() {
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
var htmlContent string
err := chromedp.Run(ctx,
chromedp.Navigate("https://example.com"),
chromedp.OuterHTML("body", &htmlContent),
)
if err != nil {
log.Fatal(err)
}
fmt.Println(htmlContent)
}
Gestion des sessions et des cookies
Si un site web nécessite la gestion d'un login ou d'une session, vous pouvez gérer les cookies et les sessions à l'aide de http.CookieJar.
Exemple de gestion des cookies :
paquet principal
import (
"fmt
"log"
"net/http
"net/http/cookiejar"
"github.com/PuerkitoBio/goquery"
)
func main() {
jar, _ := cookiejar.New(nil)
client := &http.Client{Jar : jar}
// Se connecter et sauvegarder les cookies
loginURL := "https://example.com/login"
loginForm := url.Values{}
loginForm.Set("username", "your_username")
loginForm.Set("password", "your_password")
res, err := client.PostForm(loginURL, loginForm)
if err != nil {
log.Fatal(err)
}
res.Body.Close()
// Accéder à une page protégée
url := "https://example.com/protected-page"
res, err = client.Get(url)
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
doc, err := goquery.NewDocumentFromReader(res.Body)
if err != nil {
log.Fatal(err)
}
doc.Find(".protected-content").Each(func(index int, item *goquery.Selection) {
content := item.Text()
fmt.Println(content)
})
}
Restriction et limitation du débit
Pour éviter d'être bloqué par les sites web, il faut mettre en place une limitation de débit en introduisant des délais entre les requêtes.
Exemple de limitation de débit :
paquet principal
import (
"fmt
"log"
"net/http
"time"
"github.com/PuerkitoBio/goquery"
)
func main() {
urls := []string{"https://example.com/page1", "https://example.com/page2"}
for _, url := range urls {
res, err := http.Get(url)
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
doc, err := goquery.NewDocumentFromReader(res.Body)
if err != nil {
log.Fatal(err)
}
doc.Find(".item").Each(func(index int, item *goquery.Selection) {
title := item.Find(".title").Text()
fmt.Println(title)
})
// Délai pour éviter d'être bloqué
time.Sleep(2 * time.Second)
}
}
Traitement des requêtes AJAX
Certains sites web chargent des données de manière dynamique par le biais de requêtes AJAX. Vous pouvez capturer et reproduire ces requêtes à l'aide d'outils tels que les outils de développement du navigateur pour trouver les points de terminaison de l'API.
Exemple de récupération de données à partir d'un point de terminaison de l'API AJAX :
paquet principal
import (
"encodage/json"
"fmt"
"log"
"net/http"
)
type Item struct {
Title string `json : "title"``.
}
func main() {
url := "https://example.com/api/items"
res, err := http.Get(url)
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
var items []Item
if err := json.NewDecoder(res.Body).Decode(&items) ; err != nil {
log.Fatal(err)
}
for _, item := range items {
fmt.Println(item.Title)
}
}
Traitement des Captchas et des mécanismes anti-scraping
Les sites web utilisent souvent des CAPTCHA et d'autres mécanismes anti-scraping. Bien que la résolution programmatique des CAPTCHA soit complexe et souvent contraire aux conditions de service, vous pouvez utiliser des techniques telles que la rotation des agents utilisateurs et des proxys pour éviter d'être détecté.
Exemple d'agents utilisateurs rotatifs :
paquet principal
import (
"fmt
"log"
"net/http
"math/rand
"time"
)
func main() {
userAgents := []string{
"Mozilla/5.0 (Windows NT 10.0 ; Win64 ; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3",
"Mozilla/5.0 (Macintosh ; Intel Mac OS X 10.11 ; rv:54.0) Gecko/20100101 Firefox/54.0",
// Ajoutez d'autres agents utilisateurs ici
}
client := &http.Client{}
rand.Seed(time.Now().UnixNano())
for i := 0 ; i < 5 ; i++ {
req, err := http.NewRequest("GET", "https://example.com", nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("User-Agent", userAgents[rand.Intn(len(userAgents))])
res, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
res.Body.Close()
fmt.Println("Request sent with user-agent :", req.Header.Get("User-Agent"))
}
}
Utilisation des mandataires
Pour protéger davantage votre IP contre l'interdiction, vous pouvez utiliser des proxys. Des services comme OkeyProxy ou MacroProxy proposent des solutions de proxy.
En tant que l'un des meilleurs fournisseurs de proxy, OkeyProxy est pris en charge par HTTP/HTTPS/SOCKS et fournit plus de 150 millions d'adresses IP résidentielles réelles, couvrant plus de 200 pays/zones, ce qui pourrait permettre à l'utilisateur d'avoir accès à des informations de qualité. éviter l'interdiction de la propriété intellectuelle et garantit la sécurité, la fiabilité et la stabilité des connexions réseau.

Exemple d'utilisation d'un proxy pour le scraping de données avec http.Client :
paquet principal
import (
"fmt
"log"
"net/http
"net/url"
)
func main() {
proxyURL, _ := url.Parse("http://proxyusername:proxypassword@proxyserver:port")
transport := &http.Transport{
Proxy : http.ProxyURL(proxyURL),
}
client := &http.Client{Transport : transport}
res, err := client.Get("https://example.com")
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
fmt.Println("Response status :", res.Status)
}
Scraping simultané
Pour accélérer le scraping, vous pouvez utiliser des goroutines pour traiter plusieurs requêtes simultanément. C'est utile pour l'analyse de grands ensembles de données.
Exemple de raclage simultané avec des goroutines :
paquet principal
import (
"fmt
"log"
"net/http
"sync"
"github.com/PuerkitoBio/goquery"
)
func scrape(url string, wg *sync.WaitGroup) {
defer wg.Done()
res, err := http.Get(url)
if err != nil {
log.Println(err)
return
}
defer res.Body.Close()
doc, err := goquery.NewDocumentFromReader(res.Body)
if err != nil {
log.Println(err)
return
}
doc.Find(".item").Each(func(index int, item *goquery.Selection) {
title := item.Find(".title").Text()
fmt.Println(title)
})
}
func main() {
urls := []string{
"https://example.com/page1",
"https://example.com/page2",
// Ajouter d'autres URLs
}
var wg sync.WaitGroup
for _, url := range urls {
wg.Add(1)
go scrape(url, &wg)
}
wg.Wait()
}
Récupérer des données à partir d'API
De nombreux sites web proposent des API pour accéder aux données. L'utilisation des API est souvent plus facile et plus efficace que le scraping HTML.
Exemple d'appel à une API :
paquet principal
import (
"encodage/json"
"fmt"
"log"
"net/http"
)
func main() {
url := "https://api.example.com/data"
res, err := http.Get(url)
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
var data map[string]interface{}
if err := json.NewDecoder(res.Body).Decode(&data) ; err != nil {
log.Fatal(err)
}
fmt.Println("Données API :", données)
}
Stockage des données
En fonction de vos besoins, vous devrez peut-être stocker les données extraites dans une base de données ou dans un fichier. Voici un exemple d'écriture de données dans un fichier CSV :
paquet principal
import (
"encodage/csv
"fmt"
"log"
"os"
"net/http"
"github.com/PuerkitoBio/goquery"
)
func main() {
file, err := os.Create("data.csv")
if err != nil {
log.Fatal(err)
}
defer file.Close()
writer := csv.NewWriter(file)
defer writer.Flush()
urls := []string{"https://example.com/page1", "https://example.com/page2"}
for _, url := range urls {
res, err := http.Get(url)
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
doc, err := goquery.NewDocumentFromReader(res.Body)
if err != nil {
log.Fatal(err)
}
doc.Find(".item").Each(func(index int, item *goquery.Selection) {
title := item.Find(".title").Text()
writer.Write([]string{titre})
})
}
fmt.Println("Données écrites dans data.csv")
}
Gestion des erreurs et journalisation
Une gestion robuste des erreurs et la journalisation sont essentielles pour le dépannage et la maintenance des scrapers. Vous pouvez utiliser les capacités de journalisation de Go ou des bibliothèques externes comme logrus pour une journalisation avancée.
Bibliothèques essentielles pour le Web Scraping en Golang
- CollyInstallation : go get -u github.com/gocolly/colly
- Goquerybibliothèque de type jQuery pour manipuler et interroger le HTML Installation : go get -u github.com/PuerkitoBio/goquery
- DemandeInstallation : go get -u github.com/imroc/req
- Les quêtes:Bibliothèque de requêtes HTTP de haut niveau, similaire à Requests de Python.installation : go get -u github.com/levigross/grequests
- ChromedpInstallation : go get -u github.com/chromedp/chromedp
- Tige:Bibliothèque moderne d'automatisation des navigateurs pour Go, mettant l'accent sur la facilité d'utilisation et les fonctionnalités modernes.installation : go get -u github.com/ysmood/rod
- Go-Selenium:Un client Selenium WebDriver pour Go, utile pour automatiser les navigateurs.installation : go get -u github.com/tebeka/selenium
- Scolly:Un wrapper autour de Colly pour simplifier le web scraping.installation : go get -u github.com/scolly/scolly
- Coup de pinceau:Un client Go pour l'API Browshot qui permet de faire des captures d'écran et de récupérer le contenu des pages web.installation : go get -u github.com/browshot/browshot-go
- Marionnettiste-go:Un portage en Go de Puppeteer, une bibliothèque Node pour contrôler Chrome sans tête.installation : go get -u github.com/chromedp/puppeteer-go
- Demandes d'informations:Bibliothèque de requêtes HTTP simple inspirée de Requests de Python Installation : go get -u github.com/deckarep/golang-set
- Httpproxy:Un serveur proxy HTTP simple pour Go, utile pour acheminer le trafic de scraping web.Installation : go get -u github.com/henrylee2cn/httpproxy
- RamperInstallation : go get -u github.com/whyrusleeping/crawling
- K6:Bien qu'il s'agisse avant tout d'un outil de test de charge, K6 peut être utilisé pour le scraping de données web grâce à ses capacités de scripting.Installation : go get -u github.com/loadimpact/k6
- Net/http:La bibliothèque standard pour faire des requêtes HTTP en Go.Installation : Intégré à Go, pas besoin d'installation séparée.
- Goquery-htmlInstallation : go get -u github.com/PuerkitoBio/goquery-html
- Httpclient:Un client HTTP de haut niveau pour Go, offrant des fonctionnalités de requête avancées.installation : go get -u github.com/aymerick/raymond
Ces bibliothèques et outils couvrent un large éventail de fonctionnalités, allant des simples requêtes HTTP à l'automatisation complète du navigateur, ce qui les rend polyvalents pour répondre à différents besoins en matière d'exploration du web.
Résumé
L'extraction de données sur le web avec Golang offre plusieurs avantages, notamment l'efficacité des performances et la facilité de concurrence. Les goroutines et les canaux légers de Go permettent de traiter plusieurs requêtes simultanées avec un minimum de ressources, ce qui en fait un outil idéal pour les tâches d'extraction de données à grande échelle. En outre, la solide bibliothèque standard de Go prend en charge des capacités d'analyse HTTP et HTML robustes, ce qui simplifie le développement d'applications d'extraction de données sur le web efficaces et fiables. Cette combinaison de vitesse, de concurrence et d'outils intégrés fait de Golang un choix convaincant pour les projets de web scraping qui requièrent de hautes performances et une grande évolutivité.