From 40c2bf927c4615ab1a1f3312e70b9bbdfb63ddfa Mon Sep 17 00:00:00 2001 From: Cedric Date: Thu, 2 Jul 2026 16:33:08 +0200 Subject: [PATCH] Actualiser api.php --- api.php | 151 +++++++++++++++++++++----------------------------------- 1 file changed, 55 insertions(+), 96 deletions(-) diff --git a/api.php b/api.php index 752eba0..6e86e28 100644 --- a/api.php +++ b/api.php @@ -153,110 +153,26 @@ function fetchFromGoUpc($ean) { return $empty; } -// ── FONCTION : SCRAPPING UPCINDEX.COM (CORRIGÉE) ── +// ── NOUVELLE FONCTION : SCRAPPING UPCINDEX.COM (MODIFIÉE AVEC MÉTADONNÉES) ── function fetchFromUpcIndex($ean) { $empty = emptyPhysicalResult(); $url = "https://www.upcindex.com/" . urlencode($ean); $html = httpGet($url, 15); if (!$html) return $empty; - // 1. Parser le JSON-LD pour le titre français et l'image (plus fiable) - if (preg_match('/]*type="application\/ld\+json"[^>]*>(.*?)<\/script>/is', $html, $jsonMatch)) { - $jsonData = json_decode($jsonMatch[1], true); - if ($jsonData && isset($jsonData['@type']) && $jsonData['@type'] === 'Product') { - // Titre français propre - if (!empty($jsonData['name'])) { - $empty['title'] = trim($jsonData['name']); - } - // Image - if (!empty($jsonData['image'])) { - $empty['poster'] = trim($jsonData['image']); - } - // Brand/éditeur - if (!empty($jsonData['brand']['name'])) { - $empty['publisher'] = trim($jsonData['brand']['name']); - } - } + // Recherche du titre + if (preg_match('/]*class="text-center"[^>]*>.*?]*itemprop="name"[^>]*>([^<]+)<\/span>/is', $html, $m)) { + $empty['title'] = trim(strip_tags($m[1])); + } elseif (preg_match('/]*>([^<]+)<\/title>/i', $html, $m)) { + $title = trim($m[1]); + $title = preg_replace('/\s*[-–]\s*UPCindex.*$/i', '', $title); + $empty['title'] = $title; } - // 2. Fallback pour le titre : meta twitter:title - if (empty($empty['title']) && preg_match('/]*name="twitter:title"[^>]*content="([^"]+)"/i', $html, $m)) { - $empty['title'] = html_entity_decode(trim($m[1]), ENT_QUOTES | ENT_HTML5, 'UTF-8'); - } - - // 3. Extraire la section product-info pour les métadonnées physiques - if (preg_match('/]*id="product-info"[^>]*itemtype="http:\/\/schema\.org\/ItemList"[^>]*>(.*?)<\/section>/is', $html, $sectionMatch)) { - $productInfo = $sectionMatch[1]; - - // Fonction helper pour extraire une valeur unique depuis dt/dd - $extractValue = function($label) use ($productInfo) { - $pattern = '/]*>' . preg_quote($label, '/') . '<\/dt>\s*]*>([^<]+)<\/dd>/is'; - if (preg_match($pattern, $productInfo, $m)) { - return trim($m[1]); - } - return ''; - }; - - // Directeur - $director = $extractValue('director'); - if (!empty($director)) { - $empty['director'] = $director; - } - - // Acteurs (peut y avoir plusieurs dd pour un seul dt) - if (preg_match('/]*>actor<\/dt>(.*?)(?=]*>([^<]+)<\/dd>/is', $actorSection[1], $actorMatches); - if (!empty($actorMatches[1])) { - $empty['actors'] = implode(', ', array_map('trim', $actorMatches[1])); - } - } - - // Aspect ratio - $aspectRatio = $extractValue('aspect ratio'); - if (!empty($aspectRatio)) { - $empty['aspect_ratio'] = $aspectRatio; - } - - // Nombre de disques - $numDiscs = $extractValue('number of discs'); - if (!empty($numDiscs) && is_numeric($numDiscs)) { - $empty['number_of_discs'] = (int)$numDiscs; - } - - // Format (peut y avoir plusieurs valeurs) - if (preg_match('/]*>format<\/dt>(.*?)(?=]*>([^<]+)<\/dd>/is', $formatSection[1], $formatMatches); - if (!empty($formatMatches[1])) { - $formats = array_map('trim', $formatMatches[1]); - // Chercher un format vidéo pertinent - foreach ($formats as $f) { - if (stripos($f, '4K') !== false || stripos($f, 'UHD') !== false) { - $empty['format'] = '4K Ultra HD'; - break; - } elseif (stripos($f, 'Blu-ray') !== false || stripos($f, 'Bluray') !== false) { - $empty['format'] = 'Blu-ray'; - break; - } elseif (stripos($f, 'DVD') !== false) { - $empty['format'] = 'DVD'; - break; - } - } - // Si pas trouvé, utiliser le premier format - if (empty($empty['format']) && !empty($formats[0])) { - $empty['format'] = $formats[0]; - } - } - } - - // Region code (pour la description) - $regionCode = $extractValue('region code'); - if (!empty($regionCode)) { - $empty['description'] = 'Region ' . $regionCode; - } - } - - // 4. Fallback pour l'image : première image produit (pas le barcode) - if (empty($empty['poster']) && preg_match_all('/]*itemprop="http:\/\/schema\.org\/image"[^>]*src="([^"]+)"/i', $html, $matches)) { + // ✅ RÉCUPÉRATION DE L'IMAGE DEPUIS UPCINDEX (première image produit) + // Chercher la première image de produit (après le barcode) + if (preg_match_all('/]*itemprop="http:\/\/schema\.org\/image"[^>]*src="([^"]+)"/i', $html, $matches)) { + // Prendre la première image de produit (pas le barcode) foreach ($matches[1] as $imgSrc) { if (strpos($imgSrc, 'barcode.png') === false && strpos($imgSrc, 'upcindex.com') !== false) { $empty['poster'] = 'https:' . $imgSrc; @@ -265,12 +181,55 @@ function fetchFromUpcIndex($ean) { } } + // ✅ RÉCUPÉRATION DES MÉTADONNÉES PHYSIQUES + // Directeur + if (preg_match('/]*>director<\/dt>\s*]*>([^<]+)<\/dd>/is', $html, $m)) { + $empty['director'] = trim($m[1]); + } + + // Acteurs + if (preg_match_all('/]*>actor<\/dt>\s*]*>([^<]+)<\/dd>/is', $html, $actorsMatches)) { + $empty['actors'] = implode(', ', array_map('trim', $actorsMatches[1])); + } + + // Format + if (preg_match('/]*>format<\/dt>\s*]*>([^<]+)<\/dd>/is', $html, $m)) { + $format = trim($m[1]); + if (stripos($format, 'DVD') !== false) $empty['format'] = 'DVD'; + elseif (stripos($format, 'Blu-ray') !== false) $empty['format'] = 'Blu-ray'; + elseif (stripos($format, '4K') !== false) $empty['format'] = '4K Ultra HD'; + } + + // Aspect ratio + if (preg_match('/]*>aspect ratio<\/dt>\s*]*>([^<]+)<\/dd>/is', $html, $m)) { + $empty['aspect_ratio'] = trim($m[1]); + } + + // Nombre de disques + if (preg_match('/]*>number of discs<\/dt>\s*]*>(\d+)<\/dd>/is', $html, $m)) { + $empty['number_of_discs'] = (int)$m[1]; + } + + // Brand/Publisher + if (preg_match('/]*>brand<\/dt>\s*]*>([^<]+)<\/dd>/is', $html, $m)) { + $empty['publisher'] = trim($m[1]); + } + + // Region code + if (preg_match('/]*>region code<\/dt>\s*]*>([^<]+)<\/dd>/is', $html, $m)) { + $empty['description'] = 'Region ' . trim($m[1]); + } + // Nettoyage du titre if (!empty($empty['title'])) { $empty['title'] = html_entity_decode($empty['title'], ENT_QUOTES | ENT_HTML5, 'UTF-8'); $empty['title'] = trim($empty['title']); } + if (!empty($empty['title'])) { + $empty['format'] = detectFormat($empty['title']); + } + return $empty; }