From 1aba912a1554096d1e287c4302cd7bd1e3d7c324 Mon Sep 17 00:00:00 2001 From: Rene Fichtmueller Date: Mon, 20 Apr 2026 22:11:24 +0200 Subject: [PATCH] fix(scrapers): fix ATGBics theme migration, NADDOD URL, disable VCELink MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ATGBics: update HTML parser from old card--product theme to new card__info theme (Shopify template changed April 2026); name now extracted from href link text instead of aria-label - NADDOD: correct ensureVendor shop URL from /collections/transceivers (404) to /collection/optical-transceivers - VCELink: disable scraper — site pivoted from optical transceivers to audio/video/cable products; all collection URLs return 404 --- packages/scraper/src/scrapers/atgbics.ts | 14 +++++--------- packages/scraper/src/scrapers/naddod.ts | 2 +- packages/scraper/src/scrapers/vcelink.ts | 5 +++++ 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/packages/scraper/src/scrapers/atgbics.ts b/packages/scraper/src/scrapers/atgbics.ts index ded5bfe..57afb56 100644 --- a/packages/scraper/src/scrapers/atgbics.ts +++ b/packages/scraper/src/scrapers/atgbics.ts @@ -144,19 +144,15 @@ function parseCategoryPage(html: string, cat: typeof CATEGORIES[number]): Atgbic const products: AtgbicsProduct[] = []; const seen = new Set(); - // Split by product cards — class="card card--product - const cardParts = html.split(/class="card card--product/); + // Split by product cards — class="card__info" (theme updated 2025, was "card card--product") + const cardParts = html.split(/class="card__info"/); for (const card of cardParts.slice(1)) { - // Name from aria-label (full descriptive name) - const nameM = card.match(/aria-label="([^"]{8,})"/); - if (!nameM) continue; - const name = nameM[1].replace(/®/g, "").replace(/\s+/g, " ").trim(); - - // Product handle from href - const hrefM = card.match(/href="\/(?:collections\/[^"]+\/)?products\/([^"?#]+)"/); + // Product handle + name from NAME + const hrefM = card.match(/href="\/products\/([^"?#]+)"[^>]*>\s*([^<]{8,}?)\s*<\/a>/s); if (!hrefM) continue; const handle = hrefM[1]; + const name = hrefM[2].replace(/®/g, "").replace(/\s+/g, " ").trim(); if (seen.has(handle)) continue; seen.add(handle); diff --git a/packages/scraper/src/scrapers/naddod.ts b/packages/scraper/src/scrapers/naddod.ts index 7e92204..f147d75 100644 --- a/packages/scraper/src/scrapers/naddod.ts +++ b/packages/scraper/src/scrapers/naddod.ts @@ -205,7 +205,7 @@ export async function scrapeNaddod(): Promise { "NADDOD", "compatible", "https://www.naddod.com", - "https://www.naddod.com/collections/transceivers", + "https://www.naddod.com/collection/optical-transceivers", ); // ── Phase 1: Discover product URLs via sitemap ──────────────────────────── diff --git a/packages/scraper/src/scrapers/vcelink.ts b/packages/scraper/src/scrapers/vcelink.ts index f578e6d..dd52e9e 100644 --- a/packages/scraper/src/scrapers/vcelink.ts +++ b/packages/scraper/src/scrapers/vcelink.ts @@ -180,6 +180,11 @@ async function fetchPage(url: string): Promise { } export async function scrapeVcelink(): Promise { + // VCELink pivoted away from optical transceivers to audio/video/cable products (April 2026). + // All transceiver collection URLs return 404. Scraper disabled until site sells optics again. + console.warn("[vcelink] Scraper disabled — site no longer sells optical transceivers (pivoted to audio/video, April 2026)"); + return; + console.log("=== Vcelink Scraper Starting ===\n"); const vendorId = await ensureVendor(