Il web scraping è una tecnica potente per estrarre dati dai siti web e Golang (Go) è un linguaggio eccellente per questo compito. Noto per le sue prestazioni e la sua efficienza, Go può gestire il web scraping con facilità. Quindi, come fare lo scraping di dati dal web con Golang? Questa guida vi guiderà attraverso il processo di scraping di pagine web utilizzando Golang, con tecniche e suggerimenti correlati.
Golang è adatto per lo scraping di dati dal web?
Prima di saperne di più sullo scraping di dati dal web con Golang, è importante capire perché scegliere Golang per lo scraping del web e quali vantaggi offre.
Golang è una scelta importante per il web scraping grazie alle sue elevate prestazioni, al modello di concorrenza efficiente e alla robusta libreria standard. Grazie alla capacità di gestire più richieste simultaneamente tramite goroutine e ai pacchetti integrati per le richieste HTTP e il parsing HTML, Go è in grado di eseguire lo scraping di grandi volumi di dati in modo efficiente. La sua semplicità e le sue capacità di gestione degli errori semplificano ulteriormente il processo di sviluppo, mentre librerie di terze parti come Colly e Goquery offrono ulteriori funzionalità. Sebbene sia meno comune di Python per lo scraping del web, i vantaggi di Go lo rendono un'opzione interessante per chi ha familiarità con il linguaggio.
Configurazione di base per lo scraping di dati web con Golang
Lo scraping di dati dal web con Go (Golang) comporta l'esecuzione di richieste HTTP per recuperare pagine web e quindi l'analisi del contenuto HTML per estrarre le informazioni desiderate. Di seguito è riportata una guida passo-passo per lo scraping di dati dal Web utilizzando Go:
-
-
Impostazione dell'ambiente
Innanzitutto, assicuratevi che Go sia installato sul vostro sistema. Non è possibile scaricarlo dal sito sito web ufficiale.
-
Installazione dei pacchetti necessari
Sono necessari alcuni pacchetti per aiutare le richieste HTTP e il parsing HTML. I pacchetti più diffusi sono net/http per le richieste HTTP e goquery per l'analisi dell'HTML.
Ottenere un pacchetto specifico eseguendo un comando del tipo:
vai a prendere github.com/PuerkitoBio/goquery
Scrivere il raschietto
Ecco una semplice dimostrazione di come raschiare i dati da un sito web usando Golang:
pacchetto principale importare ( "fmt" "log" "net/http" "github.com/PuerkitoBio/goquery" ) func main() { // URL del sito web da analizzare url := "https://example.com" // Effettua una richiesta HTTP GET res, err := http.Get(url) se err := nil { log.Fatal(err) } deferisci res.Body.Close() // Controllare il codice di stato della risposta se res.StatusCode != 200 { log.Fatalf("Failed to fetch data: %d %s", res.StatusCode, res.Status) } // Analizzare l'HTML doc, err := goquery.NewDocumentFromReader(res.Body) if err := nil { log.Fatal(err) } // Trova e stampa i dati doc.Find("h1").Each(func(index int, item *goquery.Selection) { heading := item.Text() fmt.Println(heading) }) }
Esecuzione di richieste HTTP:
http.Get(url) effettua una richiesta HTTP GET all'URL specificato.
res.Body.Close() assicura che il corpo della risposta venga chiuso dopo la lettura.Parsing dell'HTML:
goquery.NewDocumentFromReader(res.Body) analizza la risposta HTML e restituisce un oggetto goquery.Document.
Estrazione dei dati:
doc.Find("h1").Each() trova tutti gli elementi h1 nell'HTML e li itera.
item.Text() estrae il contenuto testuale di ciascun elemento h1. -
Esecuzione del raschietto
Salvate il codice precedente in un file, ad esempio main.go, ed eseguitelo utilizzando:
eseguire main.go
-
Ulteriori considerazioni
Gestione degli errori: Gestire sempre gli errori in modo appropriato per garantire che lo scraper non si blocchi inaspettatamente.
Rispettare robots.txt: Controllare il file robots.txt del sito web per assicurarsi di essere autorizzati a eseguire lo scraping.
Limitazione della velocità: Implementare la limitazione della velocità per evitare di sovraccaricare il server di richieste.
User-Agent: Impostare un'intestazione User-Agent personalizzata per identificare lo scraper, come ad esempio:
req, err := http.NewRequest("GET", url, nil)
se err := nil {
log.Fatal(err)
}
req.Header.Set("User-Agent", "Golang_Scraper/1.0")
client := &http.Client{}
res, err := client.Do(req)
se err != nil {
log.Fatal(err)
}
deferisci res.Body.Close()
// Analizza l'HTML come prima
Tecniche avanzate per lo scraping di dati web con Golang
Gestione della paginazione
Molti siti web utilizzano la paginazione per suddividere i contenuti su più pagine. Per raccogliere tutti i dati, è necessario gestire la paginazione effettuando richieste a ogni pagina in modo sequenziale.
Ecco un esempio di gestione della paginazione:
pacchetto principale
importare (
"fmt"
"log"
"net/http"
"strconv"
"github.com/PuerkitoBio/goquery"
)
func main() {
baseURL := "https://example.com/page/"
pagina := 1
per {
url := baseURL + strconv.Itoa(pagina)
res, err := http.Get(url)
se err := nil {
log.Fatal(err)
}
deferisci res.Body.Close()
if res.StatusCode != 200 {
log.Println("Non ci sono più pagine da recuperare, ci si ferma.")
break
}
doc, err := goquery.NewDocumentFromReader(res.Body)
se err != nil {
log.Fatal(err)
}
doc.Find(".item").Each(func(index int, item *goquery.Selection) {
title := item.Find(".title").Text()
fmt.Println(titolo)
})
pagina++
}
}
Gestione del contenuto renderizzato con JavaScript
Alcuni siti web utilizzano JavaScript per rendere il contenuto in modo dinamico. Go non ha un modo incorporato per eseguire JavaScript, ma è possibile utilizzare un'opzione browser senza testa come Chromedp.
go get -u github.com/chromedp/chromedp
Esempio di utilizzo di Chromedp per lo scraping di contenuti renderizzati in JavaScript:
pacchetto principale
importare (
"contesto"
"fmt"
"log"
"github.com/chromedp/chromedp"
)
func main() {
ctx, cancel := chromedp.NewContext(context.Background())
rinviare cancel()
var htmlContent stringa
err := chromedp.Run(ctx,
chromedp.Navigate("https://example.com"),
chromedp.OuterHTML("body", &htmlContent),
)
if err != nil {
log.Fatal(err)
}
fmt.Println(htmlContent)
}
Gestione di sessioni e cookie
Se un sito web richiede la gestione del login o della sessione, è possibile gestire i cookie e le sessioni utilizzando http.CookieJar.
Esempio di gestione dei cookie:
pacchetto principale
importare (
"fmt"
"log"
"net/http"
"net/http/cookiejar"
"github.com/PuerkitoBio/goquery"
)
func main() {
jar, _ := cookiejar.New(nil)
client := &http.Client{Jar: jar}
// Effettua il login e salva i cookie
loginURL := "https://example.com/login"
loginForm := url.Values{}
loginForm.Set("username", "your_username")
loginForm.Set("password", "your_password")
res, err := client.PostForm(loginURL, loginForm)
se err := nil {
log.Fatal(err)
}
res.Body.Close()
// Accedere a una pagina protetta
url := "https://example.com/protected-page"
res, err = client.Get(url)
if err := nil {
log.Fatal(err)
}
deferisci res.Body.Close()
doc, err := goquery.NewDocumentFromReader(res.Body)
se err != nil {
log.Fatal(err)
}
doc.Find(".protected-content").Each(func(index int, item *goquery.Selection) {
content := item.Text()
fmt.Println(content)
})
}
Throttling e limitazione della velocità
Per evitare di essere bloccati dai siti web, implementare la limitazione della velocità introducendo ritardi tra le richieste.
Esempio di limitazione del tasso:
pacchetto principale
importare (
"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)
}
deferisci res.Body.Close()
doc, err := goquery.NewDocumentFromReader(res.Body)
se err != nil {
log.Fatal(err)
}
doc.Find(".item").Each(func(index int, item *goquery.Selection) {
title := item.Find(".title").Text()
fmt.Println(titolo)
})
// Ritardo per evitare il blocco
time.Sleep(2 * time.Second)
}
}
Gestione delle richieste AJAX
Alcuni siti web caricano i dati dinamicamente attraverso richieste AJAX. È possibile catturare e replicare queste richieste utilizzando strumenti come gli strumenti per sviluppatori del browser per trovare gli endpoint API.
Esempio di recupero di dati da un endpoint API AJAX:
pacchetto principale
importare (
"codifica/json"
"fmt"
"log"
"net/http"
)
tipo Voce struct {
Titolo stringa `json: "titolo"`
}
func main() {
url := "https://example.com/api/items"
res, err := http.Get(url)
if err := nil {
log.Fatal(err)
}
deferisci 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)
}
}
Gestione dei Captchas e dei meccanismi anti-scraping
I siti web utilizzano spesso CAPTCHA e altri meccanismi anti-scraping. Sebbene risolvere i CAPTCHA in modo programmatico sia complesso e spesso contrario ai termini di servizio, è possibile utilizzare tecniche come la rotazione degli user agent e i proxy per evitare il rilevamento.
Esempio di rotazione degli agenti utente:
pacchetto principale
importare (
"fmt"
"log"
"net/http"
"math/rand"
"time"
)
func main() {
userAgents := []string{
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, come 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",
// Aggiungere altri user agent qui
}
client := &http.Client{}
rand.Seed(time.Now().UnixNano())
for i := 0; i < 5; i++ {
req, err := http.NewRequest("GET", "https://example.com", nil)
se 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("Richiesta inviata con user-agent:", req.Header.Get("User-Agent"))
}
}
Utilizzo dei proxy
Per proteggere ulteriormente il vostro IP dal divieto di accesso, potete utilizzare dei proxy. Servizi come OkeyProxy o MacroProxy forniscono soluzioni proxy.
Come uno dei migliori fornitori di proxy, OkeyProxy è supportato da HTTP/HTTPS/SOCKS e fornisce oltre 150 milioni di IP residenziali reali, che coprono oltre 200 paesi/aree, che potrebbero evitare il blocco dell'IP e garantisce la sicurezza, l'affidabilità e la stabilità delle connessioni di rete.

Esempio di utilizzo di un proxy per lo scraping dei dati con http.Client:
pacchetto principale
importare (
"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)
}
deferisci res.Body.Close()
fmt.Println("Stato della risposta:", res.Status)
}
Scraping concorrente
Per accelerare lo scraping, si possono usare le goroutine per gestire più richieste simultaneamente. Questo è utile per lo scraping di grandi insiemi di dati.
Esempio di scraping concorrente con goroutine:
pacchetto principale
importare (
"fmt"
"log"
"net/http"
"sync"
"github.com/PuerkitoBio/goquery"
)
func scrape(url string, wg *sync.WaitGroup) {
rinvia wg.Done()
res, err := http.Get(url)
if err := nil {
log.Println(err)
ritorno
}
deferisci res.Body.Close()
doc, err := goquery.NewDocumentFromReader(res.Body)
se err != nil {
log.Println(err)
return
}
doc.Find(".item").Each(func(index int, item *goquery.Selection) {
title := item.Find(".title").Text()
fmt.Println(titolo)
})
}
func main() {
urls := []string{
"https://example.com/page1",
"https://example.com/page2",
// Aggiungere altri URL
}
var wg sync.WaitGroup
for _, url := range urls {
wg.Add(1)
go scrape(url, &wg)
}
wg.Wait()
}
Scraping di dati da API
Molti siti web offrono API per accedere ai dati. L'uso delle API è spesso più semplice ed efficiente dello scraping dell'HTML.
Esempio di chiamata di un'API:
pacchetto principale
importare (
"codifica/json"
"fmt"
"log"
"net/http"
)
func main() {
url := "https://api.example.com/data"
res, err := http.Get(url)
if err := nil {
log.Fatal(err)
}
deferisci res.Body.Close()
var data map[string]interface{}
if err := json.NewDecoder(res.Body).Decode(&data); err := nil {
log.Fatal(err)
}
fmt.Println("Dati API:", dati)
}
Memorizzazione dei dati
A seconda delle esigenze, potrebbe essere necessario memorizzare i dati di scraping in un database o in un file. Ecco un esempio di scrittura dei dati in un file CSV:
pacchetto principale
importare (
"codifica/csv"
"fmt"
"log"
"os"
"net/http"
"github.com/PuerkitoBio/goquery"
)
func main() {
file, err := os.Create("data.csv")
if err := nil {
log.Fatal(err)
}
deferisci file.Close()
writer := csv.NewWriter(file)
defer writer.Flush()
urls := []string{"https://example.com/page1", "https://example.com/page2"}
per _, url := range urls {
res, err := http.Get(url)
if err := nil {
log.Fatal(err)
}
deferisci res.Body.Close()
doc, err := goquery.NewDocumentFromReader(res.Body)
se err != nil {
log.Fatal(err)
}
doc.Find(".item").Each(func(index int, item *goquery.Selection) {
title := item.Find(".title").Text()
writer.Write([]string{titolo})
})
}
fmt.Println("Dati scritti in data.csv")
}
Gestione e registrazione degli errori
La gestione degli errori e il logging sono essenziali per la risoluzione dei problemi e la manutenzione degli scrapers. È possibile utilizzare le funzionalità di registrazione di Go o librerie esterne come logrus per una registrazione avanzata.
Librerie essenziali per il Web Scraping in Golang
- CollyInstallazione: go get -u github.com/gocolly/colly
- Goquery:libreria simile a jQuery per manipolare e interrogare l'HTML.Installazione: go get -u github.com/PuerkitoBio/goquery
- RichiestaInstallazione: go get -u github.com/imroc/req
- Richieste di risarcimento:libreria di richieste HTTP di livello superiore, simile a Requests di Python.Installazione: go get -u github.com/levigross/grequests
- CromatopInstallazione: go get -u github.com/chromedp/chromedp
- Asta:Moderna libreria di automazione del browser per Go, con particolare attenzione alla facilità d'uso e alle caratteristiche moderne.Installazione: go get -u github.com/ysmood/rod
- Vai-SeleniumUn client Selenium WebDriver per Go, utile per automatizzare i browser.Installazione: go get -u github.com/tebeka/selenium
- Scolly:Un wrapper attorno a Colly per semplificare lo scraping del web.Installazione: go get -u github.com/scolly/scolly
- Browshot:Un client Go per l'API Browshot per scattare screenshot e scrape di contenuti da pagine web.Installazione: go get -u github.com/browshot/browshot-go
- Burattinaio-go:Un porting Go di Puppeteer, una libreria Node per il controllo di Chrome senza testa.Installazione: go get -u github.com/chromedp/puppeteer-go
- Richieste di Go:Semplice libreria di richieste HTTP ispirata a Requests di Python.Installazione: go get -u github.com/deckarep/golang-set
- Httpproxy:Un semplice server proxy HTTP per Go, utile per instradare il traffico di web scraping.Installazione: go get -u github.com/henrylee2cn/httpproxy
- Strisciare:Una libreria per la costruzione di web crawler distribuiti.Installazione: go get -u github.com/whyrusleeping/crawling
- K6Sebbene sia principalmente uno strumento per i test di carico, K6 può essere utilizzato per lo scraping di dati web grazie alle sue capacità di scripting.Installazione: go get -u github.com/loadimpact/k6
- Rete/http:La libreria standard per effettuare richieste HTTP in Go.Installazione: Integrata in Go, non necessita di installazione separata.
- Goquery-html:Un'altra libreria di parsing HTML con miglioramenti basati su Goquery.Installazione: go get -u github.com/PuerkitoBio/goquery-html
- Httpclient:Un client HTTP di alto livello per Go, che offre funzionalità di richiesta avanzate.Installazione: go get -u github.com/aymerick/raymond
Queste librerie e strumenti coprono una gamma di funzionalità, dalle semplici richieste HTTP all'automazione completa del browser, rendendoli versatili per le diverse esigenze di scraping del web.
Sintesi
Lo scraping di dati dal web con Golang offre diversi vantaggi, tra cui l'efficienza delle prestazioni e la facilità della concorrenza. Le goroutine e i canali leggeri di Go consentono di gestire più richieste simultanee con un sovraccarico minimo di risorse, rendendolo ideale per attività di estrazione di dati su larga scala. Inoltre, la solida libreria standard di Go supporta solide capacità di parsing HTTP e HTML, semplificando lo sviluppo di applicazioni di web scraping efficienti e affidabili. Questa combinazione di velocità, concorrenza e strumenti integrati rende Golang una scelta convincente per i progetti di web scraping che richiedono elevate prestazioni e scalabilità.