Actualiser api.php
This commit is contained in:
@@ -115,113 +115,68 @@ function extractYear($dateStr) {
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── DVDCover.com Scraper ──
|
|
||||||
function fetchDVDCover($title, $year = '', $format = 'bluray') {
|
function fetchDVDCover($title, $year = '', $format = 'bluray') {
|
||||||
if (empty($title)) return null;
|
if (empty($title)) return null;
|
||||||
|
|
||||||
$ua = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';
|
$ua = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';
|
||||||
$cleanTitle = cleanTitle($title);
|
$cleanTitle = cleanTitle($title);
|
||||||
|
|
||||||
// URL de recherche DVDCover
|
// On encode proprement pour l'URL
|
||||||
$searchUrl = "https://www.dvdcover.com/?s=" . urlencode($cleanTitle);
|
$searchUrl = "https://www.dvdcover.com/?s=" . urlencode($cleanTitle);
|
||||||
|
|
||||||
$html = httpGet($searchUrl, 8, $ua);
|
$html = httpGet($searchUrl, 10, $ua);
|
||||||
if (!$html) {
|
if (!$html) {
|
||||||
error_log("DVDCover: Échec recherche pour '$title'");
|
error_log("DVDCover: Erreur réseau pour '$title'");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DEBUG : Sauvegarde le contenu pour vérifier si on est bloqué
|
||||||
|
file_put_contents(__DIR__ . '/debug_scrap.html', $html);
|
||||||
|
|
||||||
|
$dom = new DOMDocument();
|
||||||
|
@$dom->loadHTML($html);
|
||||||
|
$xpath = new DOMXPath($dom);
|
||||||
|
|
||||||
|
// On cherche les liens dans les articles (Standard WordPress)
|
||||||
|
$links = $xpath->query('//article[contains(@class, "post")]//a/@href');
|
||||||
|
|
||||||
|
if ($links->length === 0) {
|
||||||
|
error_log("DVDCover: Aucun article trouvé pour '$title' (structure changée ?)");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = [
|
foreach ($links as $link) {
|
||||||
'poster' => '',
|
$coverPage = $link->nodeValue;
|
||||||
'title' => '',
|
|
||||||
'format' => $format,
|
$coverHtml = httpGet($coverPage, 10, $ua);
|
||||||
];
|
if (!$coverHtml) continue;
|
||||||
|
|
||||||
// DVDCover est un site WordPress - les articles ont la classe "post"
|
$domFiche = new DOMDocument();
|
||||||
// Chercher les liens vers les pages individuelles de covers
|
@$domFiche->loadHTML($coverHtml);
|
||||||
preg_match_all('/<article[^>]*class=["\'][^"\']*post[^"\']*["\'][^>]*>.*?<a[^>]+href=["\']([^"\']+)["\'][^>]*>.*?<\/article>/is', $html, $articles);
|
$xpathFiche = new DOMXPath($domFiche);
|
||||||
|
|
||||||
if (!empty($articles[1])) {
|
// On cherche toutes les images dans la zone de contenu
|
||||||
foreach ($articles[1] as $coverPage) {
|
// WordPress utilise souvent la classe 'entry-content' ou 'post-content'
|
||||||
if (strpos($coverPage, 'http') !== 0) {
|
$imgs = $xpathFiche->query('//div[contains(@class, "entry-content")]//img | //article//img');
|
||||||
$coverPage = 'https://www.dvdcover.com' . $coverPage;
|
|
||||||
}
|
foreach ($imgs as $img) {
|
||||||
|
$src = $img->getAttribute('src');
|
||||||
|
|
||||||
$coverHtml = httpGet($coverPage, 8, $ua);
|
// On filtre les images : on veut une jaquette, pas un logo ou une vignette 150x150
|
||||||
if (!$coverHtml) continue;
|
if (strpos($src, 'wp-content/uploads') !== false &&
|
||||||
|
strpos($src, 'logo') === false &&
|
||||||
// Extraire le titre du cover
|
strpos($src, 'icon') === false &&
|
||||||
$coverTitle = '';
|
strpos($src, '150x150') === false) {
|
||||||
if (preg_match('/<h1[^>]*class=["\'][^"\']*entry-title[^"\']*["\'][^>]*>([^<]+)<\/h1>/i', $coverHtml, $titleMatch)) {
|
|
||||||
$coverTitle = trim(strip_tags($titleMatch[1]));
|
return [
|
||||||
} elseif (preg_match('/<title[^>]*>([^<]+)<\/title>/i', $coverHtml, $titleMatch)) {
|
'poster' => $src,
|
||||||
$coverTitle = trim(strip_tags($titleMatch[1]));
|
'title' => $cleanTitle,
|
||||||
}
|
'format' => $format
|
||||||
|
];
|
||||||
// Vérifier que le titre correspond au film recherché
|
|
||||||
$coverTitleLower = strtolower($coverTitle);
|
|
||||||
$searchTitleLower = strtolower($cleanTitle);
|
|
||||||
|
|
||||||
// Score de correspondance
|
|
||||||
$score = 0;
|
|
||||||
if (strpos($coverTitleLower, $searchTitleLower) !== false) {
|
|
||||||
$score += 50;
|
|
||||||
}
|
|
||||||
if (!empty($year) && strpos($coverTitle, $year) !== false) {
|
|
||||||
$score += 30;
|
|
||||||
}
|
|
||||||
if (stripos($coverTitle, $format) !== false) {
|
|
||||||
$score += 20;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Si le score est trop bas, on ignore ce résultat
|
|
||||||
if ($score < 30) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Chercher l'image principale dans le contenu
|
|
||||||
$poster = '';
|
|
||||||
|
|
||||||
// Méthode 1 : Image dans entry-content
|
|
||||||
if (preg_match('/<div[^>]*class=["\'][^"\']*entry-content[^"\']*["\'][^>]*>.*?<img[^>]+src=["\']([^"\']+)["\'][^>]*>/is', $coverHtml, $imgMatch)) {
|
|
||||||
$poster = $imgMatch[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Méthode 2 : Image dans figure
|
|
||||||
if (empty($poster) && preg_match('/<figure[^>]*>.*?<img[^>]+src=["\']([^"\']+)["\'][^>]*>/is', $coverHtml, $imgMatch)) {
|
|
||||||
$poster = $imgMatch[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Méthode 3 : Chercher toutes les images et prendre la première valide
|
|
||||||
if (empty($poster)) {
|
|
||||||
preg_match_all('/<img[^>]+src=["\']([^"\']+\/wp-content\/uploads\/[^"\']+\.(?:jpg|jpeg|webp))["\'][^>]*>/i', $coverHtml, $allImages);
|
|
||||||
if (!empty($allImages[1])) {
|
|
||||||
foreach ($allImages[1] as $img) {
|
|
||||||
// Exclure les images de thème, logos, etc.
|
|
||||||
if (strpos($img, 'logo') === false &&
|
|
||||||
strpos($img, 'icon') === false &&
|
|
||||||
strpos($img, 'banner') === false &&
|
|
||||||
strpos($img, 'bg') === false &&
|
|
||||||
strpos($img, 'button') === false &&
|
|
||||||
strpos($img, '300x200') === false &&
|
|
||||||
strpos($img, '150x150') === false) {
|
|
||||||
$poster = $img;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Si on a une image valide, on la garde
|
|
||||||
if (!empty($poster)) {
|
|
||||||
$result['poster'] = $poster;
|
|
||||||
$result['title'] = $coverTitle;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
return (!empty($result['poster'])) ? $result : null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── API TMDB (uniquement pour les critiques) ──
|
// ── API TMDB (uniquement pour les critiques) ──
|
||||||
|
|||||||
Reference in New Issue
Block a user