Botasaurus est un framework Python de web scraping signé Omkar Cloud, présenté comme une solution tout-en-un pour créer des extracteurs. Tu écris une fonction simple, tu la décors avec @browser, @request ou @task, puis le framework ajoute autour un driver de navigateur, un client HTTP façon navigateur, du cache, de l’exécution parallèle et des exports multi-formats. C’est un méta-package, et c’est justement là que se cache l’info la plus importante : pip install botasaurus n’installe pas une seule bibliothèque dans ton environnement, il assemble une petite famille de wheels maison ainsi qu’un large arbre de dépendances transitives. Honnêtement, ce détail mécanique a été l’élément le plus intéressant que j’ai pu mesurer.
Botasaurus met en avant sa capacité à éviter la détection, et c’est précisément l’axe que cet avis n’explore pas. J’ai inventorié le framework — ce qui s’installe, ce qui s’importe, quelles méthodes existent, quel est son poids, sous quelle licence il est distribué — plutôt que de le confronter à des défenses réelles. Tous les chiffres de poids et d’import ci-dessous proviennent de pip, de python -c "import ..." et de l’inspection d’objets instanciés sans jamais leur demander de charger une page ; aucun navigateur n’a été lancé pour obtenir ces résultats. Plus tard, j’ai bien lancé des navigateurs, mais uniquement sur des pages que j’avais écrites et hébergées moi-même sur 127.0.0.1, afin de voir ce que le driver déclare de lui-même et s’il sait extraire du contenu d’une page qui se construit en JavaScript. Aucun site réel n’a été impliqué à aucun moment, aucun service anti-bot n’a été contacté ni mesuré, et aucun CAPTCHA n’a été touché. L’efficacité face à de vrais sites est volontairement hors périmètre, et je préfère le dire clairement plutôt que d’impliquer un benchmark que je n’ai pas exécuté.
Avec ce cadre posé, le résultat principal concerne l’empreinte disque, et elle est plutôt saine. Une installation propre produit un répertoire site-packages de 122,3 Mo sur 44 paquets, sur une machine où le driver au cœur du système pèse environ 4 Mo. Le framework n’est pas lourd parce que le driver serait lourd ; il l’est parce que le concept de “tout-en-un” embarque numpy, lxml, gevent et une douzaine d’autres briques pour une tâche qui consiste à récupérer du HTML. Et la deuxième moitié du constat est un chiffre qu’on voit souvent brandi comme une qualité alors qu’il ne faut pas le prendre pour tel : import botasaurus s’exécute en 0,08 ms, ce qui donne l’impression d’un framework ultra léger, alors qu’il s’agit surtout d’une porte d’entrée presque vide.
Ce qu’est réellement Botasaurus
Botasaurus — omkarcloud/botasaurus sur GitHub, avec 5 561 étoiles, 486 forks et 58 issues ouvertes au moment où j’ai récupéré les métadonnées le 14 juillet 2026 — est un framework Python, pas une simple bibliothèque à usage unique. Les versions testées étaient botasaurus 4.0.97 pour le méta-package et botasaurus-driver 4.0.92 pour le moteur sous-jacent. Le méta-package déclare requires-python >=3.7 (le driver, >=3.5), et les classifiers PyPI ne revendiquent officiellement une compatibilité que jusqu’à Python 3.11. Il s’est pourtant installé et a passé un test d’import minimal sur Python 3.14.2 sur ma machine. Cela prouve que cette installation-là fonctionne, pas que toutes les fonctionnalités seront compatibles partout.
Le classement de catégorie compte, parce qu’il détermine ce que veut dire “bon”. Botasaurus se situe du côté framework du spectre, au même niveau que Scrapy et Crawlee : tu adoptes sa structure, ses décorateurs, ses conventions, et en échange il gère toute la plomberie. C’est différent d’un driver ciblé comme nodriver, qui fournit une connexion Chrome DevTools Protocol et laisse le reste de côté. Botasaurus embarque bien un driver (botasaurus-driver), mais il l’encapsule dans un orchestrateur de tâches, une couche de cache, des sérialiseurs de sortie et un client de requêtes. Tu n’achètes pas seulement un driver ; tu adoptes un flux de travail très opinionné, avec un driver à l’intérieur.
Les trois décorateurs résument à eux seuls toute l’idée, et les trois points d’entrée existent réellement — j’ai confirmé que botasaurus.browser.browser, botasaurus.request.request et botasaurus.task.task sont bien présents et importables. @browser exécute ta fonction sur le driver de navigateur “humanisé”. @request l’exécute sur un client HTTP léger conçu pour ressembler à un navigateur. @task sert d’enveloppe générique pour tout ce qui n’entre pas clairement dans les deux premiers cas. Tu décores, et Botasaurus fournit tout le reste : exécution parallèle, réutilisation du driver, cache des résultats et exporteurs JSON, CSV, Excel et HTML. L’idée est cohérente. La vraie question est de savoir si tu veux autant de framework autour d’un scraper — c’est une question de goût, pas un défaut.
Mon avis, et la limite que je lui impose
Botasaurus est compétent, bien structuré, et fait exactement ce que les frameworks sont censés faire : rendre le cas courant plus court. Le modèle à décorateurs est propre. La licence MIT est réellement généreuse. L’installation se passe sans drame. Si je devais noter l’ergonomie de l’API, elle s’en sortirait bien.
Ce qui me revient sans cesse, c’est que l’argument phare du framework — l’anti-détection — est justement la seule chose qu’un avis responsable ne peut pas juger sans le confronter à des défenses en production. Le driver expose bien une surface d’API explicitement brandée anti-détection : j’en ai confirmé l’existence, mais je ne l’ai pas testée contre une cible réelle. C’est tout ce que je peux affirmer à ce sujet. Je ne l’ai pas pointé vers un site protégé, je n’ai pas mesuré de taux de réussite, je n’ai pas rétroconçu de mécanisme, et je n’en tirerai aucune conclusion implicite. Les méthodes existent dans la classe. Leur comportement sur de vrais sites relève d’un autre test, pas de celui-ci.
Ce qui suit est donc un inventaire de capacités, d’installation, de ressources et de licence, plus ce que le driver fait sur une page que je contrôle — une affirmation beaucoup plus étroite que celle de la plupart des avis sur cet outil, et cette étroitesse est volontaire.
Ce qu’il annonce de lui-même

Voici une question à laquelle on peut répondre sans s’approcher d’une vraie défense : quand Botasaurus pilote un navigateur, qu’est-ce que ce navigateur révèle de lui-même à la page qu’il consulte ? J’ai créé une page qui lit les éléments les plus évidents — navigator.webdriver, le user-agent, la plateforme, les langues, les compteurs de plugins et de matériel, la forme de window.chrome, les réponses de la Permissions API, la géométrie de la fenêtre et de l’écran — je l’ai servie sur 127.0.0.1, puis j’ai confronté quatre stacks à cette page : Botasaurus, nodriver, ainsi que les versions stock de Playwright et Puppeteer. Les quatre pilotaient exactement la même version de Chrome (Chrome for Testing 151.0.7922.10), donc toute différence vient de la bibliothèque et non du navigateur. Mode headless et mode fenêtré, trois exécutions chacun. Toutes les valeurs ci-dessous sont restées identiques sur les trois passages.
| Stack | Mode | navigator.webdriver | Token du user-agent | navigator.languages |
|---|---|---|---|---|
| Botasaurus 4.0.92 | headless | false | HeadlessChrome/151.0.0.0 | ["en-US"] |
| Botasaurus 4.0.92 | fenêtré | false | Chrome/151.0.0.0 | ["en-US"] |
| nodriver 0.50.3 | headless / fenêtré | false | HeadlessChrome/151 / Chrome/151 | ["en-US"] |
| Playwright 1.56.0 | headless / fenêtré | true | HeadlessChrome/151 / Chrome/151 | ["en-US","en"] |
| Puppeteer 24.16.0 | headless / fenêtré | true | HeadlessChrome/151 / Chrome/151 | ["en-US"] |
Les différences dépendent du contrôle utilisé. Face à Puppeteer standard, Botasaurus a modifié navigator.webdriver ; la liste des langues et la géométrie de fenêtre à taille nulle correspondaient, tandis que le user-agent ne différait que par le format de version. Face à Playwright standard, les écarts observés incluaient aussi la liste des langues et la géométrie de fenêtre. Face à nodriver, le booléen et les langues coïncidaient, avec seulement un format différent dans le user-agent pour les champs affichés ici. Il s’agit d’observations de divulgation par défaut, pas d’un score anti-détection.
Deux détails rendent le résultat plus intéressant qu’un simple false. Le premier concerne la manière dont la valeur apparaît. Dans les quatre stacks, la propriété reste bien le getter natif du navigateur sur Navigator.prototype — function get webdriver() { [native code] } — jamais une propriété propre injectée sur l’instance, jamais une fonction remplacée. Botasaurus ne réécrit donc pas la propriété après le chargement de la page ; la valeur est fixée au démarrage du navigateur, et la propriété elle-même n’est pas modifiée.
Le second détail nuance le marketing. En mode headless, le user-agent de Botasaurus annonce toujours HeadlessChrome/151.0.0.0 — exactement comme Puppeteer stock, exactement comme Playwright stock. En mode fenêtré, il devient Chrome/151.0.0.0, là encore à l’identique. Le constructeur Driver accepte un paramètre user_agent, donc il suffit d’un argument keyword pour le changer, mais la configuration par défaut ne masque pas la chaîne d’identification la plus célèbre de l’automatisation de navigateur.
Presque tout le reste était identique entre les quatre stacks, et il vaut mieux le dire clairement parce que cela resserre le tableau — toutes les propriétés ci-dessous étaient les mêmes sur Botasaurus, nodriver, Playwright et Puppeteer :
| Propriété | Valeur identique sur les quatre stacks |
|---|---|
platform | MacIntel |
vendor | Google Inc. |
| Plugins | cinq |
| Types MIME | deux |
pdfViewerEnabled | true |
| Cœurs logiques | douze |
| Mémoire appareil annoncée | 16 Go |
| Points de contact tactiles | zéro |
window.chrome | présent, avec app/csi/loadTimes et sans runtime |
| Chaîne du renderer WebGL | identique sur les quatre |
Le vieux classique où l’API Permissions et Notification.permission se contredisent n’est apparu nulle part — les quatre affichaient default et prompt en accord. J’ai aussi cherché dans document et window les reliquats de type cdc_ que les anciennes piles WebDriver laissaient parfois derrière elles : rien sur les quatre.
Dernier point utile avant tout déploiement : malgré ses 122 Mo, Botasaurus ne fournit ni ne télécharge de navigateur. find_chrome_executable() résout simplement vers le Chrome déjà installé sur ta machine — chez moi, /Applications/Google Chrome.app, version 150.0.7871.187 — et c’est cette version-là que le user-agent révèle ensuite. Ta flotte annonce donc le Chrome qui est effectivement présent sur tes postes, ce qui, pour un framework aussi opinionné, est un défaut par défaut étonnamment neutre.
Il faut être précis sur ce que cela mesure, et sur ce que cela ne mesure pas. C’est un relevé de ce qu’une pile automatisée divulgue quand personne ne lui demande de se cacher — utile si tu es côté défense, utile aussi si tu veux savoir ce que tes propres outils exposent. Ce n’est pas une mesure de l’importance de ces signaux pour un service donné. Je ne l’ai pas testé, et aucune ligne du tableau ne doit être lue comme l’indication d’un résultat.
Une lecture par défaut plus indulgente de ce fixture
S’annoncer est une chose ; rendre le bon HTML en est une autre. J’ai exécuté Botasaurus sur le même fixture à trois classes de contenu que le reste de ce benchmark utilise, afin que les chiffres soient comparables à ceux des autres outils mesurés ici. La page contient trois éléments : A, un lien statique dont le marqueur est littéral dans les bytes servis ; B, un nœud construit par un script inline pendant le parsing, avec son marqueur et son URL assemblés à partir de fragments de sorte qu’il faut exécuter le JavaScript pour les révéler ; et C, un nœud injecté 800 ms après l’événement load, construit de la même manière. La classe C est l’élément adversarial — une lecture effectuée au moment du load ne peut pas la voir.
| Stack | Lecture par défaut | Avec attente explicite |
|---|---|---|
| Botasaurus 4.0.92 | 2 sur 3 (A + B, manque C) | 3 sur 3 |
| nodriver 0.50.3 | 2 sur 3 | 3 sur 3 |
| Playwright 1.56.0 | 2 sur 3 | 3 sur 3 |
| Puppeteer 24.16.0 | 2 sur 3 | 3 sur 3 |
Botasaurus se place au même niveau que les gros outils. driver.get() suivi directement de driver.page_html donne un instantané au moment du chargement : le JavaScript est bien exécuté — la classe B le prouve, puisqu’elle n’existe nulle part dans les bytes servis — mais avec un délai de 800 ms il manque la classe C. Ajoute driver.wait_for_element("#delayed-injected") et tu obtiens les trois. Le résultat est stable sur trois répétitions et trois exécutions complètes de la suite, sans aucun flaky.
Le point intéressant apparaît quand on fait varier le délai d’injection pour voir à partir de quand la lecture par défaut de chaque stack cesse de capter le contenu :
| C injectée après | Botasaurus | nodriver | Playwright | Puppeteer |
|---|---|---|---|---|
| 0 ms | trouvé | trouvé | trouvé | trouvé |
| 100 ms | trouvé | — | — | — |
| 200 ms | trouvé | — | — | — |
| 300 ms | trouvé | — | — | — |
| 400 ms et plus | — | — | — | — |
Tous les autres stacks perdent la classe C dès que l’injection survient 100 ms ou plus après le chargement. Botasaurus la capte encore à 300 ms, et ne lâche prise qu’à 400 ms. C’est le framework qui joue pleinement son rôle de framework, et la cause est visible dans le constructeur : wait_for_complete_page_load=True est la valeur par défaut, donc get() revient sensiblement plus tard qu’un simple événement load. Concrètement, sa lecture par défaut coûte 401 à 431 ms de temps réel, là où nodriver tourne autour de 119 à 129 ms et Puppeteer autour de 125 à 171 ms.
Sur ce fixture local à injection retardée, l’échange représentait environ 250 ms de plus par navigation pour obtenir un snapshot par défaut plus tardif. Cela lui a permis de capter du contenu injecté jusqu’à 300 ms après le chargement dans ces exécutions ; cela ne prouve pas que Botasaurus soit plus juste sur n’importe quel site. Si tu écris des scrapers rapides sans conditions d’attente explicites, cette marge peut éviter de rater un nœud tardif. À fort volume de navigation, ou si tu attends déjà une condition précise, c’est simplement du surcoût.
Deux autres mesures pour donner l’échelle. Le lancement du navigateur plaçait Botasaurus à peu près au niveau de nodriver et Puppeteer, et bien derrière Playwright :
| Stack | Lancement du navigateur, sur plusieurs exécutions |
|---|---|
| Botasaurus 4.0.92 | 986–1151 ms |
| nodriver 0.50.3 | 910–1583 ms |
| Puppeteer 24.16.0 | 969–1008 ms |
| Playwright 1.56.0 | 282–365 ms |
Et wait_for_element() n’ajoute rien jusqu’à un délai de 300 ms — get() avait déjà dépassé le moment de l’injection — puis passe à environ 1,42 s à 400–800 ms et 2,43 s à 1500 ms.
La question des 122 Mo : ce qu’installe réellement un méta-package

Voici l’arithmétique, parce que c’est le morceau le plus utile que je puisse te donner. Une installation propre de pip install botasaurus dans un environnement virtuel neuf a produit un arbre site-packages de 122,3 Mo réparti sur 44 paquets dist-info. En retirant pip lui-même (10,9 Mo, qui relèvent de l’overhead du venv plutôt que de ce que Botasaurus a demandé), on arrive à environ 111 Mo de framework et de dépendances. Le driver du navigateur — le composant qui fait réellement l’automatisation du navigateur — représente à peu près 4 Mo de tout cela. Donc environ 107 Mo correspondent au reste de ce que le méta-package estime nécessaire.
Où va cet espace ? Les cinq dépendances transitives les plus lourdes représentent à elles seules la majeure partie du total (chaque ligne correspond à une entrée install_footprint.heaviest_deps_mb dans artifacts/raw/runs/resource_baseline.run1.json; le total est mon addition, pas un champ du fichier) :
| Paquet | Taille sur disque |
|---|---|
| numpy | 30,9 Mo |
| lxml | 19,2 Mo |
| botasaurus_requests | 12,6 Mo |
| gevent | 11,3 Mo |
| pygments | 8,4 Mo |
| Cinq paquets cumulés | 82,4 Mo (30,9 + 19,2 + 12,6 + 11,3 + 8,4) |
Le fait que numpy soit l’élément le plus volumineux m’a fait lever un sourcil — c’est une bibliothèque de calcul matriciel intégrée dans un outil dont le rôle est de récupérer et parser des pages web. Ce n’est pas absurde, juste un peu massif pour la mission. Les frameworks accumulent des dépendances utilitaires, et il est évident qu’une brique de l’arbre a besoin d’opérations sur des tableaux. C’est simplement beaucoup de machine pour un tel usage.
À titre de comparaison, le driver ciblé nodriver pèse environ 17,2 Mo sur 6 paquets sur la même machine — soit environ 7x moins. (Ce chiffre ne vient pas de ce package : il correspond à install_footprint.site_packages_total_mb dans le artifacts/raw/runs/resource_baseline.run1.json de nodriver, mesuré lors d’une exécution séparée sur le même hôte, et 122,3 ÷ 17,2 = 7,1.) Aucun de ces nombres n’est un défaut, et il ne s’agit pas d’un classement de capacités ; c’est la différence de coût mécanique entre un framework “batteries incluses” et un driver plus ciblé. Dans un conteneur, l’empreinte site-packages mesurée compte pour la couche applicative. Ce n’est pas la taille totale de l’image, et ce test n’a ni mesuré le temps de build ni le temps de déploiement à froid.
Un dernier point sur l’empreinte : lors de l’inspection, la première utilisation de from botasaurus.request import request a déclenché un téléchargement ponctuel d’environ 12,8 Mo. L’exécution capturée n’a pas identifié suffisamment bien l’artefact et sa destination pour que j’intègre ce chiffre comme un ajout stable à l’empreinte installée. Cela montre néanmoins que ce chemin de code peut nécessiter un accès réseau lors de la première utilisation, ce qu’il vaut mieux reproduire dans ta propre image avant un déploiement sans réseau.
Le chiffre d’import qui ment
Le temps d’import à froid est l’endroit où une lecture naïve des chiffres devient trompeuse. Mesuré sur sept sous-processus frais, import botasaurus au niveau supérieur tombe à une médiane de 0,08 ms. Le citer isolément donne l’impression du framework le plus léger de la catégorie.
Ce n’est pas le cas. C’est rapide parce qu’il n’y a presque rien à importer. Le package botasaurus de niveau supérieur n’expose aucun __version__ et un namespace public presque vide — l’import fait à peine quelque chose, justement parce que le package contient presque rien. Le vrai coût à prendre en compte pour un outil CLI ou un cold start serverless, c’est l’import du moteur : from botasaurus_driver import Driver prend environ 135 ms, stable à quelques millisecondes près d’une exécution à l’autre. C’est le vrai coût fixe avant même qu’une page soit chargée. Et une fois le module du driver importé, la mémoire résidente tourne autour de 29 à 30 Mo — là encore, avant qu’un seul processus Chrome n’existe. Lance un navigateur réel, et cela grimpe nettement ; je n’ai pas mesuré la mémoire avec un navigateur en cours d’exécution, donc je n’indiquerai pas de chiffre.
La leçon est petite mais nette : si import botasaurus est instantané, c’est parce que le package de niveau supérieur est creux, pas parce que le framework est bon marché. Pour dimensionner un cold start, mesure l’import dont tu dépends réellement.
Forme de l’API : 99 méthodes derrière une porte presque vide

La classe Driver du moteur expose 99 méthodes publiques — une surface large qui couvre la navigation, les requêtes d’éléments, les cookies et le stockage local, les actions souris et clavier, les captures d’écran, la gestion des onglets, le passage CDP et l’envoi de fichiers. Le constructeur prend 18 paramètres, ce qui donne une bonne idée des réglages disponibles : 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, et quelques autres. En tant qu’API de construction, cela couvre les contrôles habituels d’un wrapper de navigateur.
Le piège de forme se situe au niveau supérieur, et il est bénin mais réel. import botasaurus donne un namespace presque vide — pas de __version__, presque aucun nom public de niveau supérieur. Tout ce que tu utilises réellement vit dans des sous-modules : from botasaurus.browser import browser, Driver, from botasaurus.request import request, from botasaurus.task import task. Si tu cherches botasaurus.__version__ pour journaliser la build en cours, tu ne le trouveras pas ; il faut passer par importlib.metadata. Rien de tout cela ne casse quoi que ce soit. Ce n’est juste pas l’agencement auquel la plupart des développeurs Python s’attendent instinctivement, et le savoir t’évite cinq minutes de confusion le premier jour.
Une observation documentaire à propos des méthodes signalées plus haut est tout à fait recevable et reste dans mon périmètre : parmi les méthodes nommées anti-détection qui existent, seules 2 disposent d’une docstring dans le code. Les autres se contentent de s’auto-décrire par leur nom, avec une documentation détaillée disponible sur le site externe plutôt que dans le code installé. C’est une remarque de localisation, pas une appréciation de qualité — beaucoup de bonnes bibliothèques conservent leur prose hors du code — mais si ton réflexe consiste à lire le source pour comprendre une méthode, cette partie-là te dira surtout son nom, pas son comportement.
Licence : MIT, jusque dans le driver
Le méta-package et botasaurus-driver revendiquent tous deux une licence MIT, avec le classifier standard License :: OSI Approved :: MIT License. MIT est permissive : pas d’obligation de copyleft, pas d’exigence d’ouvrir ton propre code, peu de friction pour une adoption commerciale. C’est un vrai contraste, non négligeable, avec nodriver, le driver anti-détection voisin, distribué sous AGPL-3.0 — une licence copyleft dont la clause d’usage réseau inquiète beaucoup de services juridiques. Si la licence est un critère bloquant pour toi, la position MIT de Botasaurus est un vrai point en sa faveur.
La réserve est encore une fois la forme de méta-package. Cette licence MIT permissive s’applique aux wheels maison publiées par Botasaurus. Elle ne couvre pas automatiquement la quarantaine de paquets transitifs tirés lors de l’installation, chacun ayant sa propre licence. J’ai confirmé le MIT de niveau supérieur sur les paquets publiés par Omkar Cloud ; je n’ai pas audité la licence de chaque dépendance de l’arbre. Pour un projet perso, cette nuance compte rarement. Pour une adoption à l’échelle d’une entreprise soucieuse de sa chaîne logicielle, cet arbre d’une quarantaine de paquets est précisément le genre de chose à faire passer dans ton propre scanner de licences avant de te lancer — non pas parce que j’ai trouvé un problème, mais parce que je n’ai pas vérifié, et qu’un méta-package est exactement l’endroit où une licence inattendue peut se cacher.
Avantages et inconvénients
Avantages :
- Conception claire en trois décorateurs (
@browser/@request/@task), avec les trois points d’entrée bien présents — le framework raccourcit le cas courant. - Licence MIT sur le méta-package et sur le driver, un vrai contraste avec l’AGPL-3.0 d’un driver comparable. Permissive, adaptée au commercial, sans copyleft.
- Surface de driver très large : 99 méthodes publiques et un constructeur à 18 paramètres couvrant les besoins classiques de l’automatisation navigateur.
- Installation et tests d’import réussis sur Python 3.14.2 et 3.12.13, au-delà de la liste des classifiers (qui s’arrête à 3.11) ; la compatibilité runtime globale n’a pas été démontrée.
- La fenêtre de lecture par défaut la plus indulgente des stacks que j’ai mesurées : elle capte encore du contenu injecté 300 ms après le chargement, là où nodriver, Playwright et Puppeteer le perdent à 100 ms.
wait_for_complete_page_load=Truefait réellement quelque chose. navigator.webdriverressort àfalsepar défaut, là où les contrôles stock renvoienttrue, sans patcher la propriété — le descripteur reste le getter natif du navigateur.- Le concept “batteries incluses” est assumé : cache, parallélisme, réutilisation du driver et exports JSON/CSV/Excel/HTML sont intégrés au framework, pas ajoutés à la main.
Inconvénients :
- Lourd sur disque : 122,3 Mo sur 44 paquets, soit environ 7x un driver ciblé, principalement à cause de dépendances comme numpy (30,9 Mo) et lxml (19,2 Mo) plutôt qu’à cause du driver lui-même, qui pèse environ 4 Mo.
- Le rassurant 0,08 ms d’import au niveau supérieur est trompeur ; l’import du moteur dont tu dépends réellement tourne autour de 135 ms, et la mémoire après import se situe vers 29 à 30 Mo avant tout navigateur.
- Cette lecture par défaut plus généreuse ne vient pas gratuitement : 401 à 431 ms par navigation et lecture, contre 119 à 129 ms pour un driver plus léger sur la même page et le même Chrome.
- En mode headless, le user-agent annonce toujours
HeadlessChromepar défaut, exactement comme les contrôles stock ; le paramètreuser_agentexiste dans le constructeur, mais rien ne le configure pour toi. - Pour 122 Mo, aucun navigateur n’est inclus : il pilote le Chrome déjà présent sur l’hôte, donc la version révélée dépend de ce qui est installé sur ton parc.
- La première utilisation de
@requesta déclenché ici un téléchargement ponctuel d’environ 12,8 Mo ; l’artefact et la destination n’étaient pas assez bien capturés pour considérer cela comme un incrément d’empreinte stable. - Le package de niveau supérieur est presque vide et n’expose pas
__version__; l’API réelle et la version se trouvent ailleurs, moins intuitivement. - La plupart des méthodes nommées anti-détection n’ont pas de docstring dans le code, donc lire le source te donnera les noms, pas le comportement.
En dehors de ce que couvrent ces chiffres, et donc non testé ici : tout ce qui touche à l’efficacité anti-bot réelle en conditions de production (hors périmètre par conception), la mémoire par page, la gestion des proxys et des profils, le débit à grande échelle, et tout système autre que macOS arm64. Les chiffres d’empreinte et d’import ont été produits sans lancer le moindre navigateur ; les chiffres de rappel et de divulgation proviennent de navigateurs qui n’ont jamais parlé qu’à un fixture sur 127.0.0.1.
Pour qui c’est, et qui devrait passer son tour
Botasaurus convient si tu veux un framework plutôt qu’une pièce détachée. Si tu démarres un projet de scraping depuis un fichier vide et que tu préfères adopter une structure plutôt qu’en assembler une — des décorateurs pour les points d’entrée, du cache et du parallèle gérés, des exporteurs intégrés — c’est une option cohérente sous licence MIT. MIT est permissive, mais ton mode d’usage et de distribution mérite quand même la vérification de conformité habituelle. Les équipes qui pensent déjà en termes de Scrapy ou de Crawlee trouveront le positionnement familier.
Passe ton tour, ou au minimum réfléchis à deux fois, si ta cible de déploiement est sensible à la taille. Une installation de 122 Mo avec numpy et gevent dans l’arbre, c’est beaucoup à embarquer dans un conteneur minimal lorsque ton besoin réel est simplement « piloter un navigateur et extraire quelques champs ». Un driver ciblé te donne l’automatisation pour une fraction du poids, au prix d’écrire toi-même tout ce qui l’entoure. Et passe ton chemin si ce que tu cherches est une réponse sur l’efficacité anti-détection, parce que c’est justement la seule chose que je n’ai pas testée — tu te reposerais alors sur une promesse marketing que je n’ai ni confirmée ni infirmée.
Alternatives, et où Thunderbit se place
Le cadrage honnête d’abord : Botasaurus est gratuit, sous MIT, et auto-hébergé. C’est toi qui gères la flotte, les mises à jour et toute la chaîne de dépendances — les 44 paquets, dans leur totalité — y compris les correctifs, la conformité de licence et ce que numpy décidera de faire dans une future version. Pour beaucoup d’équipes, cette maîtrise est précisément ce qu’elles veulent, et aucun service managé ne bat “un framework que tu as déjà” en coût brut.
Dans l’open source, les comparaisons utiles se font par forme. Si tu es du côté framework avec Botasaurus, Scrapy et Crawlee sont les pairs évidents à considérer — matures, très opinionnés, chacun avec ses conventions. Si tu veux du Markdown prêt pour les LLM à partir d’une page plutôt qu’un framework de crawl, Crawl4AI et Trafilatura, orienté contenu, sont précisément pensés pour cela. Si tu aimes l’angle Python et anti-détection mais souhaites quelque chose de plus léger qu’un méta-package, Scrapling mérite un coup d’œil ; et si le langage compilé n’est pas un obstacle, la bibliothèque Go Colly échange le rendu JavaScript contre de la vitesse et une empreinte minuscule. Toute option qui pilote un navigateur, Botasaurus inclus, hérite du profil de coût détaillé dans notre comparaison Playwright vs Puppeteer : les vrais navigateurs ne sont pas bon marché à exécuter, et c’est en partie pour cela que le framework autour d’eux pèse ce qu’il pèse.
L’entrée d’une API managée se situe à un autre endroit du même pipeline. Botasaurus est la pile développeur auto-hébergée ; Thunderbit vend la version managée, pensée pour les mêmes développeurs. L’Open API ne comporte que deux endpoints. POST /distill (1 crédit) renvoie une page en Markdown propre, prêt pour les LLM, avec rendu et anti-bot gérés côté serveur, donc sans provisionner ni navigateur ni arbre de dépendances. POST /extract (20 crédits) renvoie du JSON structuré à partir d’un schéma JSON que tu définis, avec renderMode positionné sur none, basic ou full selon le niveau de navigateur réellement nécessaire à la page. Les deux existent aussi en version batch jusqu’à cent URLs d’un coup. Il existe un serveur MCP pour agents et assistants de code — thunderbit_suggest_fields est gratuit et te dit ce qu’une page expose avant que tu ne dépenses quoi que ce soit — ainsi qu’une CLI via npx @thunderbit/thunderbit-cli pour cron et CI. Pour les non-développeurs qui préfèrent ne toucher à rien de tout cela, l’extension Chrome utilise le même moteur dans un outil no-code, et les guides de la chaîne YouTube de Thunderbit couvrent les flux de travail les plus courants.
Le vrai arbitrage concerne l’endroit où se situe l’effort, pas lequel est “meilleur”. Botasaurus garde le framework, la flotte de navigateurs, les dépendances, l’infrastructure et la maintenance de ton côté de la ligne, sans frais éditeur par requête ; le calcul, la bande passante, les proxys et l’exploitation ont malgré tout un coût. Une API managée enlève le rendu et le JSON structuré de tes épaules, puis facture à l’appel — tu peux comparer cela à une solution auto-hébergée sur la page de tarifs.
Essaie Thunderbit pour l’extraction de données web
Verdict
Botasaurus est un candidat sérieux si tu cherches un framework Python tout-en-un et acceptes son empreinte de dépendances. La conception en trois décorateurs est claire, la surface du driver est large, et l’installation ainsi que les tests d’import ont réussi sur des versions de Python plus récentes que celles couvertes par ses classifiers. Sur mon fixture local, sa lecture par défaut a aussi capté du contenu injecté 300 ms après le chargement, là où les autres stacks testées l’ont raté à 100 ms ; c’est un résultat lié au fixture, pas un classement général.
Mais il faut calibrer correctement les promesses. C’est une installation de 122 Mo et 44 paquets, dont le driver ne pèse qu’environ 4 Mo, le reste étant constitué de numpy, lxml, gevent et compagnie — environ 7x un driver ciblé, et ce poids se retrouve dans ton image Docker et ton temps de déploiement à froid. Le import botasaurus de 0,08 ms est une porte d’entrée vide, pas un framework léger ; l’import du moteur à ~135 ms est le vrai coût. Cette lecture par défaut plus indulgente ajoute environ 250 ms à chaque navigation. Et sur la seule question de divulgation par défaut que j’ai pu juger réellement, l’image est plus étroite que ce que le marketing laisse entendre : un seul booléen diffère de Puppeteer stock, le user-agent headless dit toujours HeadlessChrome, et toutes les autres propriétés mesurées étaient identiques entre les quatre stacks. La promesse anti-détection qui vend l’outil est justement la seule chose que cet avis ne note pas — j’ai confirmé que ces méthodes existent, j’ai piloté le driver sur une page de ma propre machine, puis je me suis arrêté là, volontairement. Connais l’empreinte, ignore le chiffre flatteur d’import, et traite le discours stealth comme une question ouverte, et Botasaurus restera un framework honnête qui fait exactement le travail d’un framework. Si tu t’attends à un driver ultra léger, le temps de build Docker te rappellera vite la réalité.
Essaie Thunderbit pour l’extraction de données web Get Started Free
FAQ
Botasaurus est-il gratuit, et sous quelle licence est-il distribué ?
Oui, il est gratuit et sous licence MIT — le méta-package botasaurus comme le moteur botasaurus-driver portent tous deux le classifier MIT approuvé par l’OSI. MIT est permissive, donc il n’y a pas d’obligation de copyleft et son usage commercial est simple, ce qui constitue un vrai contraste avec certains drivers anti-détection comparables publiés sous AGPL-3.0. Une réserve toutefois : MIT couvre les paquets publiés par Omkar Cloud, mais pas automatiquement la quarantaine de dépendances transitives installées, donc il faut lancer ta propre analyse de licence avant une adoption d’entreprise à grande échelle.
Quelle est la taille d’une installation Botasaurus, et pourquoi import botasaurus semble-t-il instantané malgré tout ?
Une installation propre de pip install botasaurus a produit chez moi un arbre site-packages de 122,3 Mo sur 44 paquets. Le driver de navigateur lui-même ne pèse qu’environ 4 Mo — le poids vient du méta-package qui tire un large arbre de dépendances, dominé par numpy (30,9 Mo), lxml (19,2 Mo), botasaurus_requests (12,6 Mo), gevent (11,3 Mo) et pygments (8,4 Mo). C’est environ 7x l’empreinte d’un driver ciblé comme nodriver sur la même machine. Rien de tout cela n’est un défaut ; c’est le prix du “tout inclus”, et cela compte surtout pour la taille de l’image conteneur. C’est dans le temps d’import que cette empreinte se cache : import botasaurus tourne autour de 0,08 ms, mais uniquement parce que le package de niveau supérieur est presque vide — pas de __version__, presque aucun nom public, donc l’import ne fait presque rien. L’import qui coûte réellement est celui du moteur, from botasaurus_driver import Driver, à environ 135 ms, avec une mémoire résidente autour de 29 à 30 Mo après cet import et avant tout démarrage de navigateur. Tu dimensionnes un cold start serverless ? Mesure l’import du moteur, pas celui du package vide de niveau supérieur.
Qu’est-ce que Botasaurus révèle sur lui-même, et a-t-il été testé contre de vrais systèmes anti-bot ?
La première moitié a été mesurée ; la seconde a été volontairement exclue. Sur une page que j’ai servie depuis 127.0.0.1, en pilotant exactement la même version de Chrome que les contrôles : navigator.webdriver revient à false, là où Playwright stock et Puppeteer stock renvoient tous deux true. Cette valeur est fixée au lancement du navigateur, pas via un patch de la propriété — le descripteur reste bien le getter natif de Chrome. Au-delà de ce booléen, presque tout correspondait aux contrôles : même chaîne de plateforme, cinq plugins, douze cœurs logiques, 16 Go de mémoire appareil annoncée, même forme de window.chrome, pas de contradiction Permissions API, et aucun reliquat de type cdc_ dans document ou window. En mode headless, le user-agent affiche toujours HeadlessChrome/151.0.0.0, comme les deux contrôles — le constructeur Driver accepte bien un paramètre user_agent, mais rien ne le règle automatiquement. Quant à l’efficacité réelle : je n’ai jamais pointé le driver vers un site public, jamais contacté un service anti-bot et jamais touché à un CAPTCHA. Le driver comporte bien un ensemble de méthodes au nom anti-détection, dont j’ai confirmé l’existence, mais je ne les ai ni appelées, ni testées contre une cible, ni mesuré leur taux de réussite, ni décrit leur mécanisme. Le tableau de divulgation ci-dessus te dit ce que la stack annonce, et rien sur qui écoute ni sur la manière dont ce public réagit.
Botasaurus gère-t-il correctement le contenu rendu en JavaScript ?
Oui, et son comportement par défaut est plus indulgent que la plupart. Sur un fixture à trois classes de contenu, driver.get() + driver.page_html renvoie 2 sur 3 avec un délai d’injection de 800 ms — le JavaScript est bien exécuté, mais la lecture arrive avant que le contenu le plus tardif n’apparaisse — tandis que driver.wait_for_element() renvoie 3 sur 3. La particularité est l’endroit où la lecture par défaut s’arrête : Botasaurus capte encore du contenu injecté 300 ms après le chargement, là où nodriver, Playwright et Puppeteer le perdent déjà à 100 ms. C’est wait_for_complete_page_load=True dans le constructeur, et cela coûte environ 250 ms par navigation.
Comment importer et utiliser Botasaurus après l’installation ?
Pas comme tu le devinerais peut-être. Le namespace de niveau supérieur botasaurus est presque vide, donc la vraie API vit dans les sous-modules : from botasaurus.browser import browser, Driver, from botasaurus.request import request et from botasaurus.task import task. Tu décores une fonction simple avec @browser, @request ou @task, et le framework gère le driver, le cache et les sorties autour. Comme botasaurus.__version__ n’existe pas, utilise importlib.metadata si tu dois journaliser la build en cours.


