Boxing Day Sales Tracker UK 2026: Prices in GBP
Track UK Boxing Day and January sales in GBP: which retailers can be scraped, when to start, and how to compare an item's Black Friday and Boxing Day price.
Published · Updated · By Omar Eldeeb
Boxing Day 2026 is Saturday 26 December (the bank holiday moves to Monday 28 December). To track UK Boxing Day and January sales, record the items you want from Black Friday week onward, check them daily from about 20 December into mid-January through a UK connection, and compare each item's Boxing Day price with its own Black Friday price, in GBP.
This guide covers the UK-specific parts: which retailers a scraper can reach, why the currency needs a UK exit, a real Black-Friday-versus-Boxing-Day comparison script, and the schedule. The retail sales calendar has the rest of the season.
The UK timeline
| Date | Event | Tracking step |
|---|---|---|
| ~20 Nov - Mon 30 Nov 2026 | Black Friday week to Cyber Monday (Black Friday is 27 November). Amazon UK's 2025 Black Friday Week ran 20 November to 1 December. | Take full snapshots. These are the prices Boxing Day has to beat. |
| 1 - 19 Dec | Christmas shopping | Weekly snapshot is enough for sale items you don't need before Christmas. |
| ~20 Dec | Start of daily checks | A daily schedule from here catches a sale whenever a retailer launches it, including online launches before the 26th. |
| Fri 25 Dec | Christmas Day | Keep the schedule running. |
| Sat 26 Dec | Boxing Day | Compare with the Black Friday snapshot. |
| Mon 28 Dec | Boxing Day substitute bank holiday | |
| January | January sales, with further reductions at some retailers | Daily until you buy or the price returns. |
Which UK retailers can be tracked
The scraper used below, E-commerce Product Scraper Pro, lists every site it supports in its README. For the UK as of October 2026:
| Status | UK retailers |
|---|---|
| Supported | John Lewis, Marks & Spencer, Waitrose, Aldi UK, plus any Shopify or WooCommerce shop |
| Best-effort | amazon.co.uk (95% of deliverable products in the latest cloud tests), Sainsbury's, Tesco, Ocado, Morrisons, Lidl, Iceland, IKEA UK, Zalando UK, Wayfair UK, idealo UK |
| Not supported | Argos, AO, Boots, Next, Smyths Toys, Superdrug, Co-op, Asda, Costco UK, eBay UK |
Several big Boxing Day names are in the last row. They block automated access on every route the actor tested, so you'll need another way to watch them (their own wish lists or price alerts, or checking by hand). Some best-effort sites read only the first page of a listing or search (Sainsbury's, Ocado, Morrisons, Lidl, IKEA); for those, track product URLs.
Use a UK connection and check the currency
UK retailers can localise prices by visitor location. A scraper running in a US data centre may get a page priced in dollars, or no price at all because the item "cannot be dispatched" to that location. Two things prevent this:
- Pin the exit to the UK. In this actor,
proxyCountry: "GB"pins the residential connection to the UK. Amazon storefronts are pinned to their own currency automatically. - Check
currencyon every row. It's an ISO code (GBP), separate from the symbol the page printed (currencyRaw, for example£). Filter out any row that isn'tGBPbefore comparing.
Take a snapshot
This takes one snapshot of two UK searches and one Amazon UK product, in GBP, and saves it to a JSON file. Install the client with pip install apify-client.
import json, os
from decimal import Decimal
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run_input = {
"listingUrls": [
{"url": "https://www.johnlewis.com/search?search-term=coffee+machine"},
{"url": "https://www.marksandspencer.com/search?searchTerm=jumper"},
],
"detailsUrls": [{"url": "https://www.amazon.co.uk/dp/B088NRLMPV"}],
"proxyCountry": "GB",
"maxItemsPerStartUrl": 2,
"maxProductResults": 5,
}
run = client.actor("constructive_calm/ecommerce-product-scraper-pro").call(
run_input=run_input, max_total_charge_usd=Decimal("0.25"), logger=None
)
rows = client.dataset(run["defaultDatasetId"]).list_items(
fields="site,url,name,price,currency,originalPrice,inStock,scrapedAt"
).items
with open("snapshot_today.json", "w", encoding="utf-8") as f:
json.dump(rows, f, ensure_ascii=False, indent=1)
for r in rows:
print(r["site"], r["price"], r["currency"], r.get("originalPrice"), r["name"][:45])Real output, 2026-10-20:
marksandspencer 18 GBP None Air-Yarn Crew Neck Jumper
marksandspencer 18 GBP None Air-Yarn Striped Crew Neck Jumper
amazon-gb 7.49 GBP 9.49 Anker USB C to USB C Charger Cable, 60W (3A)
johnlewis 629 GBP None Sage Barista Express Bean to Cup Coffee Machi
johnlewis 599.95 GBP None Sage Barista Express Impress Bean to Cup CofforiginalPrice is the store's own was-price, filled only when the page shows one higher than the current price. Treat it as the retailer's claim; your Black Friday snapshot is the evidence.
For the real season, save one file per run (for example snapshot_2026-11-27.json and snapshot_2026-12-26.json) and use product URLs for the items you care about, because search results reorder.
Compare Black Friday with Boxing Day
This joins two snapshots on the product URL and prints the change per item. It works on any two JSON exports with url, site, name and price fields.
import json, sys
def load(path):
return {r["url"]: r for r in json.load(open(path, encoding="utf-8")) if r.get("price") is not None}
before, after = load(sys.argv[1]), load(sys.argv[2])
print(f"{'site':<16}{'before':>9}{'after':>9}{'change':>9} name")
for url in sorted(before.keys() & after.keys()):
b, a = before[url], after[url]
pct = (a["price"] - b["price"]) / b["price"] * 100
flag = " <- cheaper now" if pct <= -5 else (" <- dearer now" if pct >= 5 else "")
print(f"{a['site']:<16}{b['price']:>9.2f}{a['price']:>9.2f}{pct:>8.1f}% {a['name'][:38]}{flag}")
print(f"{len(before.keys() & after.keys())} products in both snapshots; "
f"{len(after.keys() - before.keys())} new, {len(before.keys() - after.keys())} missing")Run as python compare_snapshots.py snapshot_black_friday.json snapshot_boxing_day.json. Boxing Day 2026 hasn't happened yet, so here it is on two real snapshots taken two days apart (18 and 20 October 2026). The earlier one was a larger run, which is why 35 of its products are "missing" from the small one:
site before after change name
amazon-gb 9.49 7.49 -21.1% Anker USB C to USB C Charger Cable, 60 <- cheaper now
johnlewis 629.00 629.00 0.0% Sage Barista Express Bean to Cup Coffe
johnlewis 599.95 599.95 0.0% Sage Barista Express Impress Bean to C
marksandspencer 18.00 18.00 0.0% Air-Yarn Striped Crew Neck Jumper
4 products in both snapshots; 1 new, 35 missingEven over two quiet October days, the Amazon UK cable moved by 21%, which is why one price on one day tells you little. Read the result like this:
- Cheaper on Boxing Day by more than a few percent: the sale beat Black Friday for that item.
- Same or dearer: Black Friday was the better moment. Don't buy just because a sale banner is up.
- Missing in the later snapshot: sold out or delisted. If it reappears in January, a monitor run will flag it
back-in-stock.
A Boxing Day schedule
| Window | Cadence | Cron (UTC) | Input |
|---|---|---|---|
| ~20 Nov - 30 Nov | daily, full snapshot | 0 7 * * * |
product URLs, proxyCountry: "GB" |
| 1 Dec - 19 Dec | weekly | 0 7 * * 1 |
same |
| 20 Dec - mid-Jan | daily, monitorMode: true, onlyChanges: true |
0 7 * * * |
same URLs, so the comparison chain isn't reset |
07:00 UTC is 07:00 in the UK in winter. Keep the same URL list for the whole season: the actor's monitor state is keyed by the exact set of input URLs, and changing one starts a fresh comparison. To be told when something drops, route price-down rows to email or Slack (price drop alerts).
What it costs
Pay per event, prices from the actor's README. FREE tier: $0.0048 per product row, $0.0012 per unchanged product with onlyChanges, $0.0004 per listing page, $0.005 per run start, and $0.018 per MB of residential traffic on sites that need it. John Lewis, Marks & Spencer, Waitrose and Aldi go through datacenter connections, so they have no traffic fee. amazon.co.uk is mostly residential, measured at 0.3-0.5 MB per product and billed at 89% of the measured traffic.
- 100 John Lewis products, one full snapshot (FREE): 100 × $0.0048 + $0.005 = $0.485
- 100
amazon.co.ukproducts, one full snapshot (FREE): 100 × $0.0048 = $0.48, plus 27-45 billed MB × $0.018 = $0.49-$0.81, plus $0.005 = about $0.97-$1.30. On GOLD the README puts the same run at $0.46-$0.71.
Apify's free plan gives $5 of usage every month, no credit card required. The actor has no free trial of its own.
To set up the input without writing code, use the free e-commerce price tracker query builder. It shows a fixed example of the output shape, not live prices.
Related guides
- Retail sales calendar 2026-2027
- Black Friday price tracker, where your comparison snapshot comes from
- Christmas price tracker
- UK grocery price tracker
Disclosure: I built the Apify actor and this site. The comparison script works on exports from any tool.
Sources: GOV.UK bank holidays (Boxing Day substitute day, 28 December 2026), Amazon UK: Black Friday Week 2025, the actor's README (supported-sites matrix, residential traffic table, pricing), and live actor runs on 2026-10-18 and 2026-10-20.
Quick answers
When is Boxing Day 2026?
Saturday 26 December 2026. Because it falls on a weekend, the bank holiday is moved to Monday 28 December 2026 in England, Wales, Scotland and Northern Ireland.
Are Boxing Day sales better than Black Friday in the UK?
It depends on the item. Some lines are cheaper in the post-Christmas clearance and others were cheapest in Black Friday week. The only reliable way to tell is to record the same product's price in both periods and compare them, which is what this guide sets up.
When do the January sales end in the UK?
Each retailer sets its own end date, and some run well into January, sometimes with further reductions. Keep a daily check going until the item you want is either bought or back at full price.
Why does a UK product page show prices in dollars or euros?
The page was fetched from a connection outside the UK and the site localised the price. Fetch through a UK connection, for example with proxyCountry set to GB in the scraper, and check the currency code on every row.