Come funziona l'API di scraping, richiesta per richiesta
Invii una sola richiesta HTTP con un URL. Da lì al JSON che torna indietro viene scelto un IP di uscita, viene rispettato un paese, si ritenta oltre i blocchi, può partire un browser e una pagina diventa campi. Questa pagina ripercorre quel tragitto in ordine. È la versione utile di "pensiamo noi alle parti difficili" — se stai valutando un'API di web scraping, dovresti sapere esattamente quali parti e dove sono i limiti.
L'unica richiesta che invii
Tutto è un solo POST con un header X-Api-Key. POST /v1/extract con un url e una mappa fields è la richiesta che la maggior parte delle persone usa quasi sempre; POST /v1/fetch restituisce invece l'intera pagina, come HTML, testo visibile, Markdown o byte grezzi. Non c'è nessuna sessione da stabilire, nessun crawler da configurare e nessuno stato da conservare tra le chiamate. Ogni parametro qui sotto è una chiave nello stesso corpo JSON.
C'è anche un forward proxy grezzo, se quello che vuoi è l'accesso HTTP alla pagina da parte tua invece dei dati strutturati. Punta qualsiasi client su di esso con la tua chiave API come username e valgono gli stessi controlli di rotazione, paese e sessione. Il resto di questa pagina descrive entrambi, perché condividono un solo motore.
Passo 1: la scelta di un'uscita
Ogni richiesta esce per impostazione predefinita da un indirizzo IP diverso. Non gestisci una lista di proxy, non ruoti nulla e non ti occupi di un pool che invecchia — invii un URL e l'indirizzo viene scelto per te, nuovo, a ogni richiesta.
Quali indirizzi ti vengono offerti dipende dal tuo piano. Ai piani a pagamento vengono offerte prima le uscite ISP e datacenter premium, poi una riserva più ampia di indirizzi controllati di continuo, poi un ultimo tentativo perché una richiesta pagata non fallisca solo perché nessuna uscita era libera. Il piano Free è servito da un pool pubblico ad alta latenza — stessa rotazione, stesse funzioni, indirizzi più lenti che i target difficili bloccano più spesso. È esattamente a questo che serve il piano gratuito: prototipazione e test.
Targeting per paese
Aggiungi "country": "us" — qualsiasi codice ISO di paese — e la richiesta parte da quel paese. Sul proxy grezzo si scrive -country-us aggiunto alla tua chiave. Conta più di quanto sembri: prezzi, disponibilità, lingua e a volte l'intera pagina cambiano a seconda di dove sembra provenire la richiesta, e un prezzo statunitense raccolto da un IP europeo è sbagliato in silenzio, non palesemente rotto.
Un dettaglio implementativo che vale la pena dire, perché non è l'approccio ovvio: risolviamo il paese di ogni indirizzo direttamente, a lotti, invece che facendo una richiesta attraverso di esso. Geolocalizzare un proxy usandolo significa che solo i proxy usati di recente hanno un paese noto, quindi la quota di pool targetizzabile è sempre una frazione del pool attivo. Risolvere direttamente mantiene di fatto l'intero pool attivo targetizzabile per paese.
Sessioni sticky
La rotazione è la scelta giusta finché non lo è più. Un login, un carrello, un modulo a più passaggi o qualsiasi cosa dietro un cookie di sessione ha bisogno dello stesso IP su più richieste, perché il sito sorveglia esattamente lo schema in cui una sessione salta tra paesi diversi a metà del checkout. Passa "session": "some-name" e quel nome resta fissato a un solo IP di uscita per circa dieci minuti, poi ruota. Usa un nome di sessione distinto per ogni utente o lavoro logico. Le sessioni sticky funzionano su ogni piano, Free incluso, e non costano nulla in più.
Passo 2: il ritentativo, e perché i blocchi sono gratis
Questa è la parte che vale la pena capire bene, perché è qui che un'API di scraping o si guadagna il suo prezzo o ti fattura in silenzio i propri fallimenti.
Quando torna una risposta, decidiamo se è una risposta del target o un sintomo dell'uscita che abbiamo scelto. Un 403, un 429, un 407, un timeout, un 5xx, un errore dello scudo CDN — quelli dicono "questo IP non è gradito", non "questo è il contenuto della pagina". Quindi scartiamo del tutto la risposta, passiamo a un'altra uscita e riproviamo. Non te ne viene mai consegnata una, e non ne paghi mai una.
L'altra direzione è altrettanto voluta. Un 400, 401, 404, 410 o 451 è una risposta autentica del target sulla tua richiesta, quindi te la passiamo direttamente invece di bruciare altre tre uscite per scoprire che la pagina davvero non c'è. Gli stati del target vengono trasmessi invariati; non traduciamo le risposte del sito nelle nostre.
Vale la pena conoscere due limiti. Le richieste non idempotenti — un POST, un PUT — non vengono mai ritentate, perché ritentarne una potrebbe inviare un modulo o piazzare un ordine due volte; un'uscita fallita su un POST comunque non si paga, semplicemente non riproviamo in automatico. E se tutte le uscite provate falliscono, ricevi un errore non fatturato invece dell'ultima spazzatura che abbiamo visto. Fatturare alla consegna significa che non c'è nulla da consegnarti e nulla da addebitare.
Imparare dai blocchi
Quando un target blocca una richiesta con un 403, 429 o 451, registriamo quale dominio ha bloccato quale paese di uscita per il tuo account e la volta dopo instradiamo quel dominio attraverso altri paesi. Avviene in modo asincrono e non rallenta mai la richiesta che l'ha innescato. Su un lavoro lungo contro un sito a cui una certa regione non piace, è la differenza tra un ciclo di ritentativi e una rotta che si stabilizza.
Passo 3: il rendering, quando la pagina ha bisogno di un browser
Molte pagine sono un guscio che si assembla da solo in JavaScript. Recuperarne una in modo semplice ti dà un div vuoto e un riferimento a un bundle. Aggiungi "render": true e guidiamo un Chrome reale, lasciamo girare la pagina, poi leggiamo il DOM e applichiamo i tuoi selettori a ciò che la pagina è davvero diventata.
Abbinalo a "wait_for" impostato su un selettore CSS per attendere finché quell'elemento non esiste prima di leggere — molto più affidabile che indovinare una durata di attesa, perché aspetta la cosa che ti interessa e non un numero scelto a caso. Per contenuti che compaiono solo dopo un'interazione, actions esegue prima dei passaggi scriptati: scroll, click, wait, wait_for e fill, che coprono lo scroll infinito e i contenuti dietro un pulsante. device: "mobile" esegue il rendering come telefono se il layout mobile è quello che vuoi, e fingerprint: true presenta un'identità di browser coerente con il paese scelto — fuso orario, locale, navigator.languages — così il rendering si legge come un client reale di quella regione.
Un rendering non è un recupero con un flag attivato. Scarica tutto ciò che la pagina richiede — script, fogli di stile, immagini, font, tracker — e occupa uno slot di browser per tutta la durata. Misurato su 14 pagine in un browser reale, un rendering scarica tra circa 1 e 300 volte i byte della stessa pagina recuperata in modo semplice, con una mediana intorno a 17 volte e l'e-commerce pieno di immagini all'estremo superiore. Per questo si fattura 5 unità di richiesta invece di 1, e 10 se vuoi anche uno screenshot.
È anche il motivo per cui block_resources costa 1. Saltare immagini, font e media lascia del tutto invariato il DOM che leggono i tuoi selettori ed elimina circa il 40% del trasferimento su una pagina pesante. Se stai estraendo campi e non guardando figure, è il valore predefinito che vuoi. I rendering hanno un tetto di 5 al secondo per account su ogni piano; per qualsiasi cosa più lenta o più pesante, POST /v1/jobs la esegue in modo asincrono con un budget di cinque minuti e può chiamare un webhook quando finisce.
Passo 4: trasformare la pagina in campi
A questo punto c'è un documento. Quello che ti torna indietro dipende da cosa hai chiesto, e ci sono tre modi per chiedere.
Una mappa fields di selettori CSS o XPath restituisce un oggetto data con una chiave per campo, su ogni piano incluso Free — e quando un selettore non si compila, il campo è null e una voce field_errors lo nomina, così "la pagina non ha un prezzo" e "il tuo selettore è rotto" non sono mai la stessa risposta. Un prompt descrive invece i campi in parole semplici, adattandosi a markup che non hai mai visto, su Scale e superiori. E POST /v1/fetch ti restituisce il documento stesso come html, text, markdown o byte grezzi, a una unità di richiesta.
Cosa torna indietro, e quanto costa
Una sola risposta JSON, con lo stato del target trasmesso invariato e il paese di uscita indicato in un header. Fino a 20 URL possono condividere una sola chiamata via POST /v1/batch, ciascuno fatturato come una propria richiesta consegnata. Tutto ciò che dura a lungo va a POST /v1/jobs, che restituisce subito un id e poi si interroga o invia a un webhook che indichi tu — firmato con HMAC-SHA256 così puoi verificare che venga da noi. I rifiuti dovuti al tuo piano rispondono tutti con un code stabile e leggibile da una macchina e un fallback che ti dice cosa fare invece, così scrivi un solo ramo di codice anziché confrontare frasi in inglese.