trackbee
EN DE
Back to site
← The Trackbee blog

Why we take a screenshot instead of scraping the DOM

L
Lena · May 6, 2026 · 6 min read

The first version of Trackbee scraped HTML. It worked on a Tuesday. By Friday, Otto had shipped a redesign, MediaMarkt had moved the price into a new wrapper, and we had three engineers writing CSS selectors at midnight.

We rebuilt the capture flow around a different premise: don't read the page, look at it.

The DOM-scraper trap

A scraper has to know two things: where to look on a given site, and how to re-find that spot when the site changes. The first part is tedious. The second part is a full-time job. The shops we care about — Amazon, Otto, MediaMarkt, Best Buy — ship layout changes almost weekly. They A/B-test price displays. They lazy-load. They render the same price into three different DOM nodes depending on whether you scrolled.

Every per-site selector is a piece of debt that comes due on someone else's schedule.

What we do instead

When you click the bee icon, the extension captures a screenshot of the visible tab and sends it to our server in Frankfurt. A vision-language model running locally on a small fleet of Macs reads the picture and returns three things: the product name, the price, and the currency.

No selectors. No per-site rules. The same code path works on Amazon and on a one-page Shopify store nobody has ever heard of.

Then comes the second step

A VLM call is too slow and too expensive to run every six hours on every tracked product. So we do it exactly once, at capture time, and use the result to teach Playwright where the price lives in the DOM.

Playwright opens the same URL, searches the rendered DOM for the price string the VLM returned, and writes back a unique CSS selector for the element containing it. That selector is what the cron job re-checks every six hours. The expensive read happens once. The cheap read happens forever.

What happens when the site redesigns

The selector starts returning nothing, or returns something that doesn't parse as a price. Our cron job notices, increments a failure counter on the tracked product, and after two consecutive failures, re-runs the capture pipeline from scratch: new screenshot, new VLM call, new Playwright selector.

The user sees nothing. The tracker keeps working. That's the entire pitch for the design.

What it costs

A VLM inference call is in the order of a fraction of a cent. We run them on hardware we already own. The Playwright step is a few seconds of CPU on a residential-proxied browser. Compared to the cost of an engineer babysitting per-site scrapers, the math is not close.

The trade-off we made: capture is a few seconds slower than a pure scraper would be. We think that's a fair price for a tracker that doesn't break every time Otto's design team has a bright idea.

What we'd change

If we had infinite time, we'd run a smaller vision model on the user's device for the initial capture, so the screenshot never leaves the browser. We've prototyped it. It works on a recent MacBook and not much else. We'll revisit when the model size catches up to the average laptop.

Until then: a single screenshot, one trip to Frankfurt, and a price that keeps working.

Read next
What your shopping extensions are really selling →