Recensione di Botasaurus: un driver da 4 MB, un’installazione da 122 MB e il numero da 0,08 ms che non dovresti citare

Ultimo aggiornamento il August 14, 2026
Recensione di Botasaurus: un driver da 4 MB, un’installazione da 122 MB e il numero da 0,08 ms che non dovresti citare
Riepilogo AI

Botasaurus è un framework Python per il web scraping di Omkar Cloud che si presenta come un kit tutto-in-uno per creare scraper. Scrivi una semplice funzione, la decori con @browser, @request o @task, e il framework ci costruisce attorno un driver browser, un client HTTP dall’aspetto “da browser”, cache, parallelismo e output in più formati. È un meta-package, ed è questo il punto importante: pip install botasaurus non scarica una sola libreria nel tuo ambiente, ma mette insieme una piccola famiglia di wheel proprietarie e una vasta albero di dipendenze transitive. Quel dettaglio meccanico è risultato la cosa più interessante che sono riuscito a misurare in modo onesto.

Botasaurus è un framework Python per il web scraping di Omkar Cloud che si presenta come un kit tutto-in-uno per creare scraper. Scrivi una funzione semplice, la decori con @browser, @request o @task, e il framework costruisce attorno un driver browser, un client HTTP dall’aspetto “da browser”, cache, parallelismo e output in più formati. È un meta-package, ed è questo il punto che conta: pip install botasaurus non scarica una sola libreria nel tuo ambiente, ma mette insieme una piccola famiglia di wheel proprietarie e un ampio albero di dipendenze transitive. Quel dettaglio meccanico è risultato la cosa più interessante che sono riuscito a misurare in modo onesto.

Botasaurus si promuove soprattutto per l’anti-detection, e proprio su quell’asse questa recensione non entra. Ho catalogato il framework — cosa installa, cosa importa, quali metodi espone, quanto pesa, sotto quale licenza viene distribuito — invece di metterlo a confronto con difese reali e attive. Tutti i numeri riportati qui sotto provengono da pip, da python -c "import ..." e dall’ispezione di classi costruite ma mai incaricate di recuperare una pagina; nessun browser è stato avviato per produrne uno. Più avanti ho effettivamente avviato dei browser, ma solo su pagine scritte e servite da me stesso su 127.0.0.1, per vedere cosa il driver dichiara di sé e se riesce a leggere contenuti generati con JavaScript. In nessun momento è stato coinvolto un sito live, non è stato contattato né misurato alcun servizio anti-bot e nessun CAPTCHA è stato toccato. L’efficacia sui siti reali è volutamente fuori ambito, e preferisco dirlo subito piuttosto che insinuare un benchmark che non ho eseguito.

Con questo confine chiarito, il risultato principale riguarda il peso dell’installazione, ed è un dato tutto sommato tranquillo. Un’installazione pulita produce una directory site-packages da 122,3 MB distribuita su 44 pacchetti, su una macchina in cui il driver browser al centro del progetto pesa circa 4 MB. Il framework non è pesante perché lo sia il driver; è pesante perché “tutto incluso” significa portarsi dietro numpy, lxml, gevent e una dozzina di altri componenti per un lavoro che consiste nel recuperare HTML. E la seconda metà del risultato è un numero che spesso viene citato come un pregio ma che non andrebbe preso alla lettera: import botasaurus impiega appena 0,08 ms, che sembra un framework leggerissimo ma in realtà è solo una porta d’ingresso quasi vuota.

Cos’è davvero Botasaurus

Botasaurus — omkarcloud/botasaurus su GitHub, con 5.561 stelle, 486 fork e 58 issue aperte quando ho raccolto i metadati il 14 luglio 2026 — è un framework Python, non una libreria monouso. Le versioni che ho testato erano botasaurus 4.0.97 per il meta-package e botasaurus-driver 4.0.92 per il motore sottostante. Il meta-package dichiara requires-python >=3.7 (il driver, >=3.5), e i classificatori su PyPI indicano supporto solo fino a Python 3.11. Sul mio sistema ha installato correttamente ed è passato a un test di import su Python 3.14.2. Questa è una prova relativa a questa installazione, non una garanzia di compatibilità per ogni funzionalità.

Vale la pena fissare bene la categoria, perché è ciò che definisce cosa significa “buono”. Botasaurus si colloca nel lato framework dello spettro, nello stesso territorio di Scrapy e Crawlee: adotti la sua struttura, i suoi decorator, le sue convenzioni e, in cambio, lui si occupa dell’impianto. È una proposta diversa da un driver più mirato come nodriver, che ti offre una connessione Chrome DevTools Protocol e poi ti lascia libero di gestire il resto. Botasaurus include un driver (cioè botasaurus-driver), ma lo incapsula in un task runner, un livello di cache, serializzatori di output e un client per le richieste. Non stai comprando solo un driver; stai comprando un flusso di lavoro già impostato, con un driver al suo interno.

I tre decorator sono in miniatura l’intero progetto, e tutte e tre le entry point esistono davvero — ho verificato che botasaurus.browser.browser, botasaurus.request.request e botasaurus.task.task sono presenti e importabili. @browser esegue la tua funzione sul driver browser “umanizzato”. @request la esegue su un client HTTP leggero costruito per comportarsi come un browser. @task è il wrapper generico per tutto ciò che non rientra chiaramente nei primi due casi. Decori la funzione, e Botasaurus fornisce l’infrastruttura intorno: esecuzione parallela, riuso del driver, cache dei risultati e writer per JSON, CSV, Excel e HTML. L’idea è coerente. Se tu voglia davvero così tanto framework intorno a uno scraper è la vera domanda, ed è una questione di preferenza, non un difetto.

Il giudizio, e il limite entro cui vale

Botasaurus è competente, ben strutturato e fa quello che i framework dovrebbero fare: accorciare il caso d’uso comune. Il modello a decorator è pulito. La licenza MIT è davvero generosa. L’installazione funziona senza drammi. Se dovessi valutare l’ergonomia della superficie API, il giudizio sarebbe positivo.

Quello che continuo a considerare è che il claim principale del framework — l’anti-detection — è esattamente la parte su cui una recensione responsabile non può pronunciarsi senza puntarlo contro difese di produzione di qualcun altro. Il driver espone effettivamente una superficie API esplicitamente marchiata anti-detection: metodi la cui esistenza ho confermato, ma il cui comportamento non ho testato contro alcun target. Questo è tutto ciò che mi sento di affermare. Non l’ho puntato contro un sito protetto, non ho misurato una percentuale di successo, non ho fatto reverse engineering del meccanismo e non voglio suggerire nessuna di queste cose con il modo in cui la frase è costruita. I metodi esistono nella classe. Cosa facciano nel mondo reale è un’altra recensione, e questa non lo è.

Quello che segue è quindi un inventario di capacità, installazione, risorse e licenza, più ciò che il driver fa su una pagina che controllo io — una tesi molto più ristretta di quella che la maggior parte delle recensioni su questo strumento cerca di sostenere, e la ristrettezza è proprio il punto.

Cosa dichiara di sé

Measured results chart: Default browser disclosures by stack

Ecco una domanda a cui puoi rispondere senza andare vicino a difese reali: quando Botasaurus guida un browser, cosa rivela di sé quel browser alla pagina che sta visitando? Ho scritto una pagina che legge gli elementi più ovvi — navigator.webdriver, user-agent, piattaforma, lingue, conteggio di plugin e hardware, forma di window.chrome, risposte della Permissions API, geometria di finestra e schermo — l’ho servita su 127.0.0.1 e l’ho aperta con quattro stack: Botasaurus, nodriver, e le versioni stock di Playwright e Puppeteer come controllo. Tutti e quattro guidavano la stessa build di Chrome (Chrome for Testing 151.0.7922.10), quindi qualsiasi differenza riguarda la libreria e non il browser. Headless e headed, tre esecuzioni ciascuno. Ogni valore riportato qui sotto è rimasto invariato in tutte e tre le prove.

StackModalitànavigator.webdriverToken nello user-agentnavigator.languages
Botasaurus 4.0.92headlessfalseHeadlessChrome/151.0.0.0["en-US"]
Botasaurus 4.0.92headedfalseChrome/151.0.0.0["en-US"]
nodriver 0.50.3headless / headedfalseHeadlessChrome/151 / Chrome/151["en-US"]
Playwright 1.56.0headless / headedtrueHeadlessChrome/151 / Chrome/151["en-US","en"]
Puppeteer 24.16.0headless / headedtrueHeadlessChrome/151 / Chrome/151["en-US"]

Le differenze dipendono dal controllo che usi. Rispetto a Puppeteer stock, Botasaurus ha cambiato navigator.webdriver; la lista delle lingue e la geometria della finestra a dimensione zero coincidevano, mentre lo user-agent differiva solo nel formato della versione. Rispetto a Playwright stock, le differenze osservate includevano anche la lista delle lingue e la geometria della finestra. Rispetto a nodriver, il booleano e le lingue coincidevano, con differenze solo nel formato dello user-agent nei campi qui mostrati. Si tratta di osservazioni sulla disclosure di default, non di un punteggio anti-detection.

Ci sono due dettagli che rendono il quadro più interessante del semplice false. Il primo è come si ottiene quel valore. In tutti e quattro gli stack, la proprietà resta il getter nativo del browser su Navigator.prototypefunction get webdriver() { [native code] } — mai una proprietà propria aggiunta all’istanza, mai una funzione sostituita. Quindi Botasaurus non riscrive la proprietà dopo il caricamento della pagina; il valore viene deciso all’avvio del browser, e la proprietà in sé resta intatta.

Il secondo dettaglio è quello che mette in prospettiva il marketing. In modalità headless, lo user-agent di Botasaurus annuncia comunque HeadlessChrome/151.0.0.0 — identico a Puppeteer stock, identico a Playwright stock. In modalità headed diventa Chrome/151.0.0.0, di nuovo in modo identico. Il costruttore Driver accetta un parametro user_agent, quindi impostarne uno è solo una keyword argument di distanza, ma nella configurazione predefinita non c’è nulla che mascheri la stringa auto-identificativa più famosa dell’automazione browser.

Quasi tutto il resto era identico tra tutti e quattro gli stack, e vale la pena dirlo chiaramente perché restringe la lettura — ogni proprietà qui sotto ha restituito lo stesso valore su Botasaurus, nodriver, Playwright e Puppeteer:

ProprietàValore, identico su tutti e quattro gli stack
platformMacIntel
vendorGoogle Inc.
Plugincinque
Tipi MIMEdue
pdfViewerEnabledtrue
Core logicidodici
Memoria dispositivo riportata16 GB
Punti touchzero
window.chromepresente, con app/csi/loadTimes e senza runtime
Stringa del renderer WebGLidentica su tutti e quattro

Il vecchio caso in cui la Permissions API e Notification.permission si contraddicono non si è presentato da nessuna parte — tutti e quattro hanno restituito default e prompt in modo coerente. Ho anche scandagliato document e window alla ricerca dei residui in stile cdc_ tipici dei vecchi stack WebDriver: assenti in tutti e quattro.

Un’ultima cosa utile da sapere prima del deployment: nonostante i suoi 122 MB, Botasaurus non include né scarica un browser. find_chrome_executable() risolve il Chrome già installato sulla tua macchina — nel mio caso, /Applications/Google Chrome.app, versione 150.0.7871.187 — ed è quella versione che viene poi rivelata nello user-agent. La tua flotta annuncia il Chrome che la tua flotta ha effettivamente installato, il che per un framework così opinionated è un’impostazione sorprendentemente poco opinionata.

Bisogna dire con chiarezza cosa sia e cosa non sia. È un resoconto di ciò che uno stack automatizzato dichiara quando nessuno gli ha chiesto di nascondersi — utile se sei dalla parte di chi difende, utile se vuoi sapere cosa il tuo tooling espone all’esterno. Non è una misura di quanto tutto ciò conti per un servizio specifico. Non l’ho testato, e nessuna riga sopra va letta come se implicasse un esito.

Una lettura più indulgente del comportamento di default

Annunciarsi è una cosa; restituire l’HTML giusto è il compito vero. Ho eseguito Botasaurus sullo stesso fixture a tre classi di contenuto usato dal resto di questo benchmark, così i numeri sono confrontabili con quelli degli altri strumenti misurati qui. La pagina contiene tre elementi: A, un link statico il cui marcatore è un letterale nei byte serviti; B, un nodo costruito da uno script inline durante il parsing, con marcatore e URL assemblati da frammenti in modo che solo l’esecuzione del JavaScript li renda visibili; e C, un nodo iniettato 800 ms dopo l’evento di load, costruito nello stesso modo. La classe C è quella avversaria — una lettura presa all’evento di load non può vederla.

StackLettura predefinitaCon un’attesa esplicita
Botasaurus 4.0.922 su 3 (A + B, manca C)3 su 3
nodriver 0.50.32 su 33 su 3
Playwright 1.56.02 su 33 su 3
Puppeteer 24.16.02 su 33 su 3

Botasaurus si colloca dove si collocano i nomi più pesanti. driver.get() seguito direttamente da driver.page_html è uno snapshot preso al caricamento: renderizza correttamente il JavaScript — la classe B lo dimostra, dato che B non esiste nei byte serviti — ma con un ritardo di 800 ms perde la classe C. Aggiungi driver.wait_for_element("#delayed-injected") e ottieni tutte e tre. Stabile in tre ripetizioni e in tre esecuzioni separate dell’intera suite, senza flake.

La parte interessante emerge quando si varia il ritardo di iniezione per vedere fino a dove regge la lettura di default di ciascuno stack:

Classe C iniettata dopoBotasaurusnodriverPlaywrightPuppeteer
0 mstrovatotrovatotrovatotrovato
100 mstrovato
200 mstrovato
300 mstrovato
400 ms e oltre

Tutti gli altri stack perdono la classe C nel momento in cui l’iniezione avviene 100 ms o più dopo il load. Botasaurus la intercetta ancora a 300 ms, e rinuncia solo a 400. Questo è il framework che si comporta da framework, e la causa è nel costruttore: wait_for_complete_page_load=True è il valore predefinito, quindi get() restituisce il controllo sensibilmente più tardi di un semplice evento di load. In pratica, la sua lettura di default costa 401–431 ms di wall clock, mentre quella di nodriver costa 119–129 ms e quella di Puppeteer 125–171 ms.

Su questo fixture locale con iniezione ritardata, il compromesso è stato circa 250 ms in più per navigazione in cambio di uno snapshot di default più tardivo. Questo ha intercettato contenuti iniettati fino a 300 ms dopo il load nelle mie prove; non dimostra che Botasaurus sia più corretto su siti arbitrari. Se scrivi scraper veloci senza condizioni di attesa esplicite, questo margine può evitare di perdere un nodo che arriva tardi. Ad alto volume di navigazioni, o quando stai già aspettando una condizione precisa, è semplicemente overhead.

Altri due tempi per dare una misura. L’avvio del browser ha messo Botasaurus praticamente in linea con nodriver e Puppeteer, e molto dietro Playwright:

StackAvvio del browser, su più esecuzioni
Botasaurus 4.0.92986–1151 ms
nodriver 0.50.3910–1583 ms
Puppeteer 24.16.0969–1008 ms
Playwright 1.56.0282–365 ms

E wait_for_element() non aggiunge praticamente nulla fino a un ritardo di 300 ms — get() era già passato oltre il momento dell’iniezione — poi sale a circa 1,42 s con 400–800 ms e a 2,43 s con 1500 ms.

La questione dei 122 MB: cosa installa davvero un meta-package

Measured results chart: Heaviest installed dependencies

Ecco l’aritmetica, perché è la cosa più utile che posso consegnarti. Un pip install botasaurus pulito in un nuovo virtual environment ha prodotto un albero site-packages da 122,3 MB distribuito su 44 pacchetti dist-info. Togliendo pip stesso (10,9 MB, che è overhead del venv e non qualcosa che Botasaurus ha chiesto esplicitamente), si arriva a circa 111 MB di framework e dipendenze. Il driver browser — il componente che fa davvero l’automazione del browser — pesa circa 4 MB di tutto questo. Quindi qualcosa come 107 MB è tutto il resto che il meta-package ha deciso ti servisse.

Dove finisce questo peso? Le cinque dipendenze transitive più pesanti da sole spiegano la maggior parte del totale (ogni riga è un elemento di install_footprint.heaviest_deps_mb in artifacts/raw/runs/resource_baseline.run1.json; il totale è una mia somma, non un campo presente nel file):

PacchettoDimensione su disco
numpy30,9 MB
lxml19,2 MB
botasaurus_requests12,6 MB
gevent11,3 MB
pygments8,4 MB
Cinque pacchetti insieme82,4 MB (30,9 + 19,2 + 12,6 + 11,3 + 8,4)

numpy come voce singola più grande è stata quella che mi ha fatto alzare un sopracciglio — è una libreria di algebra lineare dentro uno strumento il cui compito è recuperare e analizzare pagine web. Non è sbagliato, in senso stretto; i framework accumulano dipendenze utilitarie e, a quanto pare, qualcosa nell’albero vuole fare matematica su array. Ma è comunque molta macchina per una commissione così semplice.

Per confronto, il driver mirato nodriver pesa circa 17,2 MB su 6 pacchetti sulla stessa macchina — quindi grossomodo 7x più leggero. (Questo dato non viene da questo pacchetto: è install_footprint.site_packages_total_mb nel proprio artifacts/raw/runs/resource_baseline.run1.json di nodriver, misurato in un’esecuzione separata sullo stesso host, e 122,3 ÷ 17,2 = 7,1.) Nessuno dei due numeri è un difetto e questa non è una classifica di capacità; è la differenza meccanica di costo tra un framework “batteries included” e un driver concentrato su un solo compito. In un container, il footprint misurato di site-packages contribuisce al layer dell’applicazione. Non è la dimensione totale dell’immagine, e questo test non ha misurato né i tempi di build né quelli di cold deploy.

Un’altra sfumatura sul footprint: durante l’ispezione, il primo uso di from botasaurus.request import request ha attivato un download una tantum di circa 12,8 MB. L’esecuzione catturata non ha identificato abbastanza bene l’artefatto e la destinazione per considerare quel valore un incremento stabile del footprint installato. Mostra però che questo percorso di codice può richiedere accesso alla rete al primo utilizzo, cosa che vale la pena verificare nel tuo ambiente prima di un deployment air-gapped.

Il numero dell’import che mente

Il cold-start dell’import è il punto in cui una lettura superficiale dei numeri diventa fuorviante. Misurato su sette import puliti in subprocess diversi, import botasaurus al livello top è risultato con una mediana di 0,08 ms. Se lo citi da solo, sembra il framework più leggero della categoria.

Non lo è. È veloce perché lì sopra c’è quasi niente. Il package botasaurus di livello top non espone alcun __version__ e ha uno spazio pubblico quasi vuoto — importarlo non fa quasi nulla perché contiene quasi nulla. Il numero che conta davvero per un tool CLI o per un cold start serverless è l’import del motore: from botasaurus_driver import Driver impiega circa 135 ms, con stabilità entro pochi millisecondi tra le varie esecuzioni. Questo è il costo fisso reale che paghi prima ancora di recuperare una pagina. E una volta importato il modulo del driver, la memoria residente si assesta intorno a 29–30 MB — di nuovo, prima che esista un processo Chrome. Se poi avvii un browser reale, la cifra cresce sensibilmente; non ho misurato la memoria con un browser in esecuzione, quindi non le attribuirò un numero.

La lezione è piccola ma netta: il fatto che import botasaurus sia immediato è una proprietà del package top-level, vuoto quasi del tutto, non del framework in sé. Se stai dimensionando un cold start, misura l’import di cui dipenderai davvero.

Forma dell’API: 99 metodi dietro una porta quasi vuota

System diagram: API shape: behind a near-empty front door

La classe Driver del motore espone 99 metodi pubblici — una superficie ampia che copre navigazione, query sugli elementi, cookie e local storage, azioni di mouse e tastiera, screenshot, gestione delle tab, passthrough CDP e upload di file. Il costruttore accetta 18 parametri, che rappresentano bene l’area configurabile: headless, proxy, profile, tiny_profile, block_images, block_images_and_css, wait_for_complete_page_load, chrome_executable_path, extensions, arguments, user_agent, window_size, lang e alcuni altri. Come API di costruzione, copre i controlli tipici di un wrapper per browser.

Il punto critico della forma sta al livello top, ed è innocuo ma reale. import botasaurus ti dà un namespace quasi vuoto — niente __version__, praticamente nessun nome pubblico al top level. Tutto ciò che usi davvero vive nei sottomoduli: from botasaurus.browser import browser, Driver, from botasaurus.request import request, from botasaurus.task import task. Se cerchi botasaurus.__version__ per loggare quale build stai usando, non lo troverai; devi passare da importlib.metadata. Non rompe nulla. Semplicemente non è il layout che la maggior parte degli sviluppatori Python si aspetta d’istinto, e saperlo ti evita cinque minuti di confusione il primo giorno.

Un’osservazione documentale sui metodi che ho segnalato prima resta legittima e rientra nel mio perimetro: tra i metodi nominati in chiave anti-detection che esistono, solo 2 hanno un docstring in codice. Gli altri si spiegano solo dal nome, mentre la documentazione per metodo vive nel sito esterno e non nel sorgente installato. È una nota di localizzazione, non un giudizio di qualità — molte ottime librerie tengono la parte discorsiva fuori dal codice — ma se il tuo flusso è “leggere il sorgente per capire il metodo”, quella superficie ti dirà soprattutto il nome e poco altro.

Licenza: MIT, fino al driver compreso

Sia il meta-package sia botasaurus-driver dichiarano MIT, con il classico classificatore License :: OSI Approved :: MIT License. MIT è permissiva: nessun obbligo di copyleft, nessun obbligo di aprire il tuo codice, attrito minimo per l’adozione commerciale. È una differenza reale e non banale rispetto a nodriver, il driver anti-detect vicino a questo progetto, che viene distribuito sotto AGPL-3.0 — una licenza copyleft con clausola sull’uso in rete che mette in allarme molti uffici legali. Se la licenza è un fattore decisivo per te, la posizione MIT di Botasaurus è un vero punto a suo favore.

Il caveat è di nuovo la forma da meta-package. Quel MIT permissivo vale per le wheel proprietarie pubblicate da Omkar Cloud. Non garantisce automaticamente la conformità per le circa 40 dipendenze transitive che l’installazione trascina con sé, ciascuna con la propria licenza. Ho verificato l’MIT al livello top sui pacchetti pubblicati da Omkar Cloud; non ho fatto audit sulla licenza di ogni dipendenza nell’albero. Per un progetto hobbistico questa distinzione conta poco. Per un’adozione aziendale dell’intero albero, in un contesto che tiene al software bill of materials, quei 40 pacchetti sono qualcosa da passare nel tuo scanner di licenze prima di impegnarti — non perché io abbia trovato un problema, ma perché non ho controllato, e un meta-package è esattamente il tipo di posto dove si può nascondere una licenza inattesa.

Pro e contro

Pro:

  • Design pulito a tre decorator (@browser / @request / @task), con tutte e tre le entry point presenti e confermate — il framework accorcia davvero il caso comune.
  • Licenza MIT sia per il meta-package sia per il driver, un contrasto reale con l’AGPL-3.0 di driver comparabili. Permissiva, adatta all’uso commerciale, senza copyleft.
  • Superficie del driver molto ampia: 99 metodi pubblici e un costruttore con 18 parametri che coprono le normali esigenze di automazione browser.
  • Installato e passato ai test smoke di import su Python 3.14.2 e 3.12.13, oltre la lista dei classifier dichiarati (che si ferma a 3.11); la compatibilità runtime completa non è stata verificata.
  • La finestra di lettura di default più tollerante tra gli stack che ho misurato: intercetta ancora contenuti iniettati 300 ms dopo il load, mentre nodriver, Playwright e Puppeteer li perdono a 100 ms. wait_for_complete_page_load=True fa davvero il suo lavoro.
  • Restituisce navigator.webdriver come false per default, mentre i controlli stock restituiscono true, senza patchare la proprietà — il descriptor resta il getter nativo del browser.
  • “Batteries included” per davvero — cache, parallelismo, riuso del driver e output JSON/CSV/Excel/HTML fanno parte del framework, non sono aggiunte esterne.

Contro:

  • Pesante su disco: 122,3 MB su 44 pacchetti, circa 7x un driver mirato, trainato da dipendenze come numpy (30,9 MB) e lxml (19,2 MB) più che dal driver stesso da ~4 MB.
  • Il rassicurante import top-level da 0,08 ms è ingannevole; l’import del motore di cui dipendi davvero è circa 135 ms, e la memoria dopo l’import è circa 29–30 MB prima di qualsiasi browser.
  • Quella finestra di lettura più ampia non è gratis: 401–431 ms per navigazione e lettura contro 119–129 ms di un driver leggero sulla stessa pagina e lo stesso Chrome.
  • Le esecuzioni headless continuano a mostrare HeadlessChrome nello user-agent di default, esattamente come i controlli stock; il parametro costruttore user_agent esiste, ma non viene impostato automaticamente.
  • Con 122 MB non include comunque un browser — controlla il Chrome già presente sull’host, quindi la versione esposta dipende da ciò che è installato nella tua infrastruttura.
  • Il primo uso di @request ha attivato in questa prova un download una tantum di circa 12,8 MB; l’artefatto e la destinazione non sono stati catturati abbastanza bene da considerarlo un incremento stabile del footprint.
  • Il package top-level è quasi vuoto e non espone __version__; l’API reale e la versione si trovano in punti meno ovvi.
  • La maggior parte dei metodi con nome anti-detection non ha docstring in codice, quindi leggendo il sorgente ottieni soprattutto i nomi, non il comportamento.

Fuori da ciò che questi numeri coprono, e quindi non testato qui: tutto ciò che riguarda l’efficacia anti-bot nel mondo reale (fuori ambito per scelta), la memoria per pagina, la gestione di proxy e profili, il throughput su larga scala e qualsiasi piattaforma diversa da macOS arm64. I dati di footprint e import sono stati prodotti senza avviare alcun browser; i dati di recupero e disclosure provengono da browser che hanno parlato solo con un fixture su 127.0.0.1.

Per chi è adatto, e chi dovrebbe evitarlo

Botasaurus funziona se vuoi un framework più che un componente. Se stai iniziando un progetto di scraping da un file vuoto e preferisci adottare una struttura piuttosto che assemblarla — decorator per le entry point, cache e parallelismo già gestiti, writer di output incorporati — questa è un’opzione coerente, con licenza MIT. MIT è permissiva, ma il tuo modello di uso e distribuzione merita comunque il consueto controllo di conformità. I team che ragionano già in termini di Scrapy o Crawlee troveranno l’impostazione familiare.

Meglio evitarlo, o almeno pensarci due volte, se il tuo target di deployment è sensibile alle dimensioni. Un’installazione da 122 MB con numpy e gevent nell’albero è molta roba da portare in un container slim quando l’esigenza reale è “guidare un browser e leggere qualche campo”. Un driver mirato ti dà l’automazione con un peso molto inferiore, al prezzo di scrivere tu l’infrastruttura intorno. E lascialo perdere del tutto se quello che vuoi è una valutazione sull’efficacia anti-detection, perché è proprio l’unica cosa che ho scelto deliberatamente di non testare — dovresti fidarti di un claim di marketing che non ho né confermato né smentito.

Alternative e dove si colloca Thunderbit

Prima il quadro onesto: Botasaurus è gratuito, con licenza MIT e self-hosted. Sei tu a gestire la flotta, gli aggiornamenti e l’intero albero delle dipendenze — tutti e 44 i pacchetti — compresi patch, compliance di licenza e tutto ciò che numpy deciderà di fare in una futura release. Per molti team questa proprietà è esattamente ciò che cercano, e nessun servizio gestito batte “un framework che hai già” sul puro costo.

Nel mondo open source, i confronti utili sono per forma. Se sei sul lato framework con Botasaurus, Scrapy e Crawlee sono i peer più ovvi da valutare — maturi, opinionati e con convenzioni proprie da adottare. Se invece vuoi Markdown già pronto per LLM da una pagina, più che un framework per strutturare un crawler, Crawl4AI e il tool orientato ai contenuti Trafilatura sono pensati proprio per quel lavoro. Se ti piace l’angolo Python e anti-detect ma vuoi qualcosa di più leggero di un meta-package, Scrapling merita un’occhiata; e se puoi usare un linguaggio compilato, la libreria Go Colly scambia il rendering JavaScript con velocità e un footprint minimo. Qualunque opzione basata su browser, Botasaurus incluso, eredita il profilo di costo descritto nel nostro confronto tra Playwright e Puppeteer: i browser reali non sono economici da eseguire, ed è anche per questo che il framework che li avvolge pesa come pesa.

Quando entra in gioco un’API gestita, si tratta di un punto diverso della stessa pipeline. Botasaurus è lo stack per sviluppatori in self-hosting; Thunderbit vende quello gestito, rivolto allo stesso tipo di sviluppatori. La Open API ha due endpoint. POST /distill (1 credito) restituisce una pagina come Markdown pulito, pronto per LLM, con rendering e anti-bot gestiti lato server, così non devi provisionare alcun browser né una dependency tree. POST /extract (20 crediti) restituisce JSON strutturato in base a uno schema JSON che definisci tu, con renderMode impostato su none, basic o full a seconda di quanto browser serve davvero alla pagina. Entrambi hanno versioni batch per un massimo di cento URL alla volta. C’è un server MCP per agenti e assistenti di coding — thunderbit_suggest_fields è gratuito e ti dice cosa espone una pagina prima che tu spenda qualcosa — e una CLI tramite npx @thunderbit/thunderbit-cli per cron e CI. Per chi non è sviluppatore e preferisce non toccare nulla di tutto questo, la estensione Chrome usa lo stesso motore come strumento no-code, e le guide sul canale YouTube di Thunderbit coprono i flussi di lavoro più comuni.

La vera differenza sta in dove vivi il lavoro, non in quale strumento sia “migliore”. Botasaurus lascia framework, flotta di browser, dipendenze, infrastruttura e manutenzione dalla tua parte della linea, senza una fee del vendor per richiesta; ma compute, banda, proxy e operatività costano comunque. Un’API gestita ti toglie di mano rendering e output strutturato secondo schema e ti addebita per chiamata — puoi confrontarla con una soluzione self-hosted nella pagina dei prezzi.

Prova Thunderbit per l’estrazione di dati web

Verdetto

Botasaurus è un candidato ragionevole se vuoi un framework Python tutto-in-uno e accetti il suo footprint di dipendenze. Il design a tre decorator è pulito, la superficie del driver è ampia e ha superato i test smoke di installazione/import su versioni di Python più recenti di quelle dichiarate nei classifier. Sul mio fixture locale, inoltre, il suo snapshot di default ha intercettato contenuti iniettati 300 ms dopo il load, mentre gli altri stack testati li hanno persi a 100 ms; è un risultato da fixture, non una classifica generale.

Bisogna però dimensionare correttamente le promesse. È un’installazione da 122 MB e 44 pacchetti, dove il driver pesa circa 4 MB e il resto è numpy, lxml, gevent e compagnia — circa 7x un driver mirato, e quel peso si riflette nella tua image Docker e nei tempi di cold deploy. L’import top-level da 0,08 ms è una porta quasi vuota, non un framework leggero; il vero numero da pagare è l’import del motore da circa 135 ms. La lettura di default più indulgente costa circa 250 ms a ogni navigazione. E sulla questione della disclosure predefinita, l’immagine che sono riuscito a misurare è più stretta di quanto il marketing lasci intendere: un booleano differisce da Puppeteer stock, lo user-agent headless continua a dire HeadlessChrome, e ogni altra proprietà che ho misurato era identica su tutti e quattro gli stack. Il pitch anti-detection che vende lo strumento è proprio la parte che questa recensione non valuta — ho confermato che quei metodi esistono, ho guidato il driver contro una pagina sulla mia macchina e mi sono fermato lì, volutamente. Conosci il footprint, ignora il numero d’import lusinghiero e tratta il marketing stealth come una domanda ancora aperta: Botasaurus è un framework onesto che fa esattamente ciò che un framework fa. Se ti aspetti un driver leggerissimo, il docker build ti sorprenderà.

Prova Thunderbit per l’estrazione di dati web Get Started Free

FAQ

Botasaurus è gratuito e sotto quale licenza rientra? È gratuito e con licenza MIT — sia il meta-package botasaurus sia il motore botasaurus-driver portano il classificatore MIT approvato OSI. MIT è permissiva, quindi non impone copyleft ed è adatta all’uso commerciale, una differenza importante rispetto a driver anti-detect comparabili distribuiti sotto AGPL-3.0. Una precisazione: l’MIT copre i pacchetti di Omkar Cloud, non automaticamente le circa 40 dipendenze transitive che l’installazione trascina, quindi prima di un’adozione aziendale sull’intero albero conviene fare una scansione licenze interna.

Quanto pesa un’installazione di Botasaurus, e perché import botasaurus sembra così veloce? Un pip install botasaurus pulito ha prodotto sul mio sistema un albero site-packages da 122,3 MB su 44 pacchetti. Il driver browser vero e proprio pesa solo circa 4 MB — il peso arriva dal meta-package che trascina un albero di dipendenze ampio, guidato da numpy (30,9 MB), lxml (19,2 MB), botasaurus_requests (12,6 MB), gevent (11,3 MB) e pygments (8,4 MB). È all’incirca 7x il footprint di un driver mirato come nodriver sulla stessa macchina. Nulla di tutto questo è un difetto; è il costo del concetto “batteries included”, e conta soprattutto per la dimensione dell’immagine container. Il tempo di import è il punto in cui quel footprint si nasconde: import botasaurus misura circa 0,08 ms, ma solo perché il package top-level è quasi vuoto — niente __version__, quasi nessun nome pubblico, quindi l’import non fa quasi nulla. L’import che conta davvero è quello del motore, from botasaurus_driver import Driver, a circa 135 ms, con memoria residente intorno a 29–30 MB dopo l’import e prima di avviare qualsiasi browser. Devi dimensionare un cold start serverless? Misura l’import del motore, non quello superficiale e quasi vuoto.

Cosa espone Botasaurus di sé, e ha mai provato a confrontarsi con sistemi anti-bot reali? La prima parte è stata misurata; la seconda è stata volutamente non affrontata. Su una pagina che ho servito da 127.0.0.1, usando la stessa build di Chrome dei controlli: navigator.webdriver torna false, mentre Playwright stock e Puppeteer stock restituiscono entrambi true. Quel valore viene impostato all’avvio del browser, non patchando la proprietà — il descriptor resta il getter nativo di Chrome. Oltre a quel booleano, quasi tutto coincideva esattamente con i controlli: stessa stringa di piattaforma, cinque plugin, dodici core, 16 GB di memoria dispositivo riportata, stessa forma di window.chrome, nessuna contraddizione della Permissions API e nessun residuo in stile cdc_ su document o window. Le esecuzioni headless continuano comunque a dichiarare HeadlessChrome/151.0.0.0 nello user-agent, esattamente come i controlli — il costruttore Driver accetta un parametro user_agent, ma non lo imposta automaticamente. Quanto all’efficacia: non ho mai puntato il driver a un sito live, non ho mai contattato un servizio anti-bot e non ho mai toccato un CAPTCHA. Il driver include anche una serie di metodi con nomi anti-detection, la cui esistenza ho confermato, ma non li ho chiamati, non ne ho testato il comportamento su alcun target, non ne ho misurato il tasso di successo e non ne descrivo il meccanismo. La tabella di disclosure qui sopra ti dice cosa lo stack annuncia, e nulla su chi lo ascolta o su cosa ne fa.

Botasaurus gestisce correttamente i contenuti renderizzati in JavaScript? Sì, e il suo default è più indulgente della maggior parte. Su un fixture con tre classi di contenuto, driver.get() + driver.page_html ha restituito 2 su 3 con un ritardo di iniezione di 800 ms — esegue correttamente il JavaScript, ma legge prima che il contenuto molto tardivo sia arrivato — mentre driver.wait_for_element() ha restituito 3 su 3. La particolarità è dove la lettura di default smette di aspettare: Botasaurus continua a intercettare contenuti iniettati 300 ms dopo il load, mentre nodriver, Playwright e Puppeteer li perdono già a 100 ms. Questo dipende da wait_for_complete_page_load=True nel costruttore, e costa circa 250 ms per navigazione.

Come faccio davvero a importare e usare Botasaurus dopo averlo installato? Non nel modo che penseresti. Il namespace top-level botasaurus è quasi vuoto, quindi la vera API vive nei sottomoduli: from botasaurus.browser import browser, Driver, from botasaurus.request import request e from botasaurus.task import task. Decori una funzione semplice con @browser, @request o @task e il framework gestisce driver, cache e output. Non esiste botasaurus.__version__, quindi se ti serve registrare quale build stai usando devi passare da importlib.metadata.

Ke
Ke
CTO di Thunderbit | Senior Data Scientist ed esperto di ML Con quasi un decennio di esperienza nel machine learning e nella data science, Ke Shen è un ex studente della Columbia University ed ex Senior Data Scientist presso Walmart Labs. Grazie a una profonda competenza, riconosciuta dai suoi pari, in Python, R, Java e statistica, condivide insight collaudati sul passaggio di algoritmi AI complessi dalla teoria a un'architettura pronta per la produzione.
Indice
Thunderbit · Agente AI per dati web

Estrai dati da qualsiasi pagina in 1 clic

Scelto da oltre 250.000 utenti
piano gratuito disponibile
Dalla pagina web al foglio di calcolo
Descrivi ciò che ti serve — l'agente AI di Thunderbit lo estrae ed esporta in Excel, Google Sheets, Airtable o Notion. Puoi iniziare gratis.
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week