I build production scrapers that get past modern bot protection and deliver clean, schema-validated datasets to commercial data marketplaces.
🌍 Open to remote roles and freelance contracts
I've been building web scrapers for over three years, and today I deliver commercial datasets to the DataBoutique (DBQ) marketplace, covering fashion, luxury, real-estate, pharmacy and grocery sites across Europe, the Middle East and the US.
What I bring to a team:
- End-to-end ownership: target analysis → link discovery → scraping → enrichment → schema conversion → upload to S3.
- Anti-bot expertise: I'm comfortable working against Cloudflare, Akamai and other WAFs using modern stealth tooling.
- Operational discipline: every job runs on a schedule with Telegram monitoring, so failures are caught in minutes, not days.
- Scale: from catalog crawls with thousands of SKUs to a 2M+ post forum scraper with deduplicated MySQL storage.
| Challenge | What I use |
|---|---|
| Cloudflare / JS challenges | SeleniumBase (UC & CDP mode), Patchright, CloakBrowser |
| Akamai & fingerprint checks | Patchright with challenge handling, session minting |
| TLS / HTTP fingerprinting | curl_cffi browser impersonation |
| IP blocks & rate limits | Rotating proxies, geo-targeted sessions, retry/backoff logic |
| Fast bulk collection | Browser mints the session once, lightweight HTTP workers do the volume |
| Hidden APIs | GraphQL interception, Algolia InstantSearch pagination, XHR reverse-engineering |
Scraping & Automation
Data Engineering, ML & Storage
Infrastructure
Every project follows the same battle-tested structure, which keeps jobs resumable, debuggable and easy to hand over:
phase1 → Discover brands / categories / listing links
phase2 → Scrape product or listing data (resumable, deduplicated)
phase3 → Enrich from detail pages (PDP)
phase4 → Convert to the target DBQ schema (e.g. E0005r, E0001, GROCERY-PLP, REAL-ESTATE-BASIC)
phase5 → Validate and upload to S3
| Project | Domain | Highlights |
|---|---|---|
| Net-a-Porter (UK) | Luxury fashion | SeleniumBase session minting + curl_cffi workers, DBQ E0005 |
| TheOutnet (Italy) | Luxury fashion | Patchright with Akamai challenge handling, full Women + Men catalog, DBQ E0001 |
| Ounass (UAE) | Luxury fashion | Brand-per-designer pipeline, DBQ E0005r |
| Mytheresa | Luxury fashion | Discount-only products for a curated brand list, configurable geo and language |
| LuisaViaRoma | Luxury fashion | SeleniumBase CDP mode to clear Cloudflare |
| Breuninger | Department store (DE) | Five-phase pipeline with S3 upload |
| Otto.de | Fashion e-commerce (DE) | Link collection → tile scraping → PDP enrichment |
| Macy's | Department store (US) | Brand-based pipeline, SKU-level rows, category enrichment |
| TheRealReal | Luxury resale | GraphQL response interception with Patchright |
| Editorialist | Fashion | Brand-ID resolver built on CloakBrowser |
| Idealista.pt | Real estate (PT) | SeleniumBase browser pool, REAL-ESTATE-BASIC schema |
| 1000farmacie.it | Pharmacy (IT) | Algolia InstantSearch pagination |
| Walmart Grocery | Grocery (US) | GraphQL pagination, GROCERY-PLP schema |
| Tieba Baidu | Forum data | 2M+ posts, MySQL storage with composite-key deduplication |
🔗 Public code lives in my repositories below. Client-delivered scrapers are summarised here without proprietary data.
I treat scrapers like production services. Each one is scheduled on an Ubuntu VM and monitored through a shared Telegram bot:
- ⏰ Cron-scheduled runs via a standard
run_scraper.shwrapper - 🔔 Instant alerts on job start, finish and failure through
notify.sh - 💬 Bot commands to check on jobs from my phone:
/projectstatus,/projectlog,/help - 🔁 One reusable setup across all active scrapers, so adding a new project takes minutes
MalariaScope is an AI-assisted tool that estimates malaria parasitemia from thin blood smear microscopy. Users upload several microscope fields from one slide, a YOLO model detects and classifies every red blood cell, and the app aggregates the counts into a single parasitemia percentage with CDC/WHO severity context. It was my capstone for the 3MTT Fellowship (Data Science, ML & AI track).
| Model | Ultralytics YOLO, trained on the BBBC041 blood smear dataset |
| Results | Unparasitized mAP50 0.976 · Parasitized mAP50 0.793 |
| Stack | Python, YOLO, OpenCV, Streamlit, NumPy, Pandas |
Judgment calls that went beyond "train a model on a dataset":
- Reframed the problem. Collapsed the dataset's 7 fine-grained classes into 2 (infected vs. not) after visually inspecting crops, and dropped leukocytes so they wouldn't corrupt the red-blood-cell denominator.
- Handled a ~28:1 class imbalance with copy-paste augmentation and a higher classification loss weight, prioritising recall on infected cells because missed infections are the costly error.
- Followed clinical counting protocol. Sums cell counts across all fields before computing one percentage, instead of averaging per-image percentages, which would misweight sparse and dense fields.
- Reported its own limits. The write-up documents the lower recall on parasitized cells and the need for cross-dataset validation.
My pharmacy training helps here: I understand the clinical problem the model is meant to serve, not just the metrics.
- B.Pharm, University of Lagos (2017 – 2024)
- 3MTT Fellowship, Data Science, ML & AI track (capstone: MalariaScope)
- Transitioned into data engineering and ML, bringing a detail-oriented, quality-first mindset from a regulated field.
I'm open to remote data engineering / web scraping roles and freelance data-extraction projects. If you need reliable, monitored data pipelines that survive bot protection, reach out on LinkedIn, Telegram or email.

