236 lines
7.6 KiB
JavaScript
236 lines
7.6 KiB
JavaScript
/**
|
|
* Collecteur Bodacc - Gel des avoirs
|
|
* Scraping léger avec politesse pour vérifier les mentions de gel des avoirs
|
|
*/
|
|
|
|
const fetch = require('node-fetch');
|
|
const { JSDOM } = require('jsdom');
|
|
|
|
const BODACC_BASE_URL = 'https://www.bodacc.fr';
|
|
const USER_AGENT = '4NK-IA-Front/1.0 (Document Analysis Tool)';
|
|
const REQUEST_DELAY_MS = 1000; // 1 seconde entre les requêtes
|
|
const REQUEST_TIMEOUT_MS = 10000; // 10 secondes timeout
|
|
|
|
/**
|
|
* Effectue une recherche sur Bodacc pour un nom/prénom donné
|
|
* @param {string} lastName - Nom de famille (obligatoire)
|
|
* @param {string} firstName - Prénom (optionnel)
|
|
* @returns {Promise<Object>} Résultat de la recherche
|
|
*/
|
|
async function searchBodaccGelAvoirs(lastName, firstName = '') {
|
|
const startTime = Date.now();
|
|
|
|
try {
|
|
console.log(`[Bodacc] Recherche gel des avoirs pour: ${lastName} ${firstName}`);
|
|
|
|
// Construction de la requête de recherche
|
|
const searchParams = new URLSearchParams({
|
|
'q': `${lastName} ${firstName}`.trim(),
|
|
'type': 'gel-avoirs',
|
|
'date_debut': '2020-01-01', // Recherche sur les 4 dernières années
|
|
'date_fin': new Date().toISOString().split('T')[0]
|
|
});
|
|
|
|
const searchUrl = `${BODACC_BASE_URL}/recherche?${searchParams.toString()}`;
|
|
|
|
// Requête avec politesse
|
|
const response = await fetch(searchUrl, {
|
|
method: 'GET',
|
|
headers: {
|
|
'User-Agent': USER_AGENT,
|
|
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
|
'Accept-Language': 'fr-FR,fr;q=0.9,en;q=0.8',
|
|
'Accept-Encoding': 'gzip, deflate, br',
|
|
'Connection': 'keep-alive',
|
|
'Upgrade-Insecure-Requests': '1'
|
|
},
|
|
timeout: REQUEST_TIMEOUT_MS
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
}
|
|
|
|
const html = await response.text();
|
|
const dom = new JSDOM(html);
|
|
const document = dom.window.document;
|
|
|
|
// Extraction des résultats
|
|
const results = extractBodaccResults(document, lastName, firstName);
|
|
|
|
// Délai de politesse avant la prochaine requête
|
|
await new Promise(resolve => setTimeout(resolve, REQUEST_DELAY_MS));
|
|
|
|
const duration = Date.now() - startTime;
|
|
console.log(`[Bodacc] Recherche terminée en ${duration}ms, ${results.length} résultats`);
|
|
|
|
return {
|
|
success: true,
|
|
duration,
|
|
results,
|
|
source: 'bodacc.fr',
|
|
searchUrl,
|
|
timestamp: new Date().toISOString()
|
|
};
|
|
|
|
} catch (error) {
|
|
const duration = Date.now() - startTime;
|
|
console.error(`[Bodacc] Erreur recherche:`, error.message);
|
|
|
|
return {
|
|
success: false,
|
|
duration,
|
|
error: error.message,
|
|
results: [],
|
|
source: 'bodacc.fr',
|
|
timestamp: new Date().toISOString()
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Extrait les résultats de la page Bodacc
|
|
* @param {Document} document - Document DOM parsé
|
|
* @param {string} lastName - Nom recherché
|
|
* @param {string} firstName - Prénom recherché
|
|
* @returns {Array} Liste des résultats trouvés
|
|
*/
|
|
function extractBodaccResults(document, lastName, firstName) {
|
|
const results = [];
|
|
|
|
try {
|
|
// Sélecteurs pour les résultats de gel des avoirs
|
|
const resultSelectors = [
|
|
'.result-item',
|
|
'.search-result',
|
|
'.bodacc-result',
|
|
'[data-type="gel-avoirs"]'
|
|
];
|
|
|
|
let resultElements = [];
|
|
for (const selector of resultSelectors) {
|
|
resultElements = document.querySelectorAll(selector);
|
|
if (resultElements.length > 0) break;
|
|
}
|
|
|
|
// Si pas de sélecteur spécifique, chercher dans le contenu général
|
|
if (resultElements.length === 0) {
|
|
const content = document.body.textContent || '';
|
|
if (content.includes('gel des avoirs') || content.includes('GEL DES AVOIRS')) {
|
|
// Résultat générique si on trouve des mentions
|
|
results.push({
|
|
name: `${firstName} ${lastName}`.trim(),
|
|
type: 'gel-avoirs',
|
|
date: new Date().toISOString().split('T')[0],
|
|
sourceUrl: BODACC_BASE_URL,
|
|
matchScore: 0.7,
|
|
description: 'Mention de gel des avoirs détectée dans les résultats Bodacc'
|
|
});
|
|
}
|
|
} else {
|
|
// Traitement des éléments de résultats spécifiques
|
|
resultElements.forEach((element, index) => {
|
|
try {
|
|
const nameElement = element.querySelector('.name, .nom, .person-name, h3, h4');
|
|
const dateElement = element.querySelector('.date, .publication-date, .date-publication');
|
|
const linkElement = element.querySelector('a[href]');
|
|
|
|
const name = nameElement ? nameElement.textContent.trim() : `${firstName} ${lastName}`.trim();
|
|
const date = dateElement ? dateElement.textContent.trim() : new Date().toISOString().split('T')[0];
|
|
const sourceUrl = linkElement ? new URL(linkElement.href, BODACC_BASE_URL).href : BODACC_BASE_URL;
|
|
|
|
// Calcul du score de correspondance basique
|
|
const matchScore = calculateMatchScore(name, lastName, firstName);
|
|
|
|
if (matchScore > 0.3) { // Seuil minimum de correspondance
|
|
results.push({
|
|
name,
|
|
type: 'gel-avoirs',
|
|
date,
|
|
sourceUrl,
|
|
matchScore,
|
|
description: `Résultat ${index + 1} de gel des avoirs sur Bodacc`
|
|
});
|
|
}
|
|
} catch (elementError) {
|
|
console.warn(`[Bodacc] Erreur traitement élément ${index}:`, elementError.message);
|
|
}
|
|
});
|
|
}
|
|
|
|
} catch (error) {
|
|
console.warn(`[Bodacc] Erreur extraction résultats:`, error.message);
|
|
}
|
|
|
|
return results;
|
|
}
|
|
|
|
/**
|
|
* Calcule un score de correspondance entre le nom trouvé et le nom recherché
|
|
* @param {string} foundName - Nom trouvé dans les résultats
|
|
* @param {string} lastName - Nom recherché
|
|
* @param {string} firstName - Prénom recherché
|
|
* @returns {number} Score entre 0 et 1
|
|
*/
|
|
function calculateMatchScore(foundName, lastName, firstName) {
|
|
const found = foundName.toLowerCase();
|
|
const last = lastName.toLowerCase();
|
|
const first = firstName.toLowerCase();
|
|
|
|
let score = 0;
|
|
|
|
// Correspondance exacte du nom de famille
|
|
if (found.includes(last)) {
|
|
score += 0.6;
|
|
}
|
|
|
|
// Correspondance du prénom si fourni
|
|
if (first && found.includes(first)) {
|
|
score += 0.4;
|
|
}
|
|
|
|
// Bonus pour correspondance exacte
|
|
if (found === `${first} ${last}`.trim().toLowerCase()) {
|
|
score = 1.0;
|
|
}
|
|
|
|
return Math.min(score, 1.0);
|
|
}
|
|
|
|
module.exports = {
|
|
searchBodaccGelAvoirs,
|
|
generateBodaccSummary
|
|
};
|
|
|
|
/**
|
|
* Génère un résumé des résultats pour le PDF
|
|
* @param {Array} results - Résultats de la recherche
|
|
* @param {string} lastName - Nom recherché
|
|
* @param {string} firstName - Prénom recherché
|
|
* @returns {Object} Résumé formaté
|
|
*/
|
|
function generateBodaccSummary(results, lastName, firstName) {
|
|
const totalResults = results.length;
|
|
const highConfidenceResults = results.filter(r => r.matchScore > 0.7);
|
|
const recentResults = results.filter(r => {
|
|
const resultDate = new Date(r.date);
|
|
const oneYearAgo = new Date();
|
|
oneYearAgo.setFullYear(oneYearAgo.getFullYear() - 1);
|
|
return resultDate > oneYearAgo;
|
|
});
|
|
|
|
return {
|
|
searchTarget: `${firstName} ${lastName}`.trim(),
|
|
totalResults,
|
|
highConfidenceResults: highConfidenceResults.length,
|
|
recentResults: recentResults.length,
|
|
hasGelAvoirs: totalResults > 0,
|
|
riskLevel: totalResults === 0 ? 'Aucun' :
|
|
highConfidenceResults.length > 0 ? 'Élevé' :
|
|
totalResults > 0 ? 'Moyen' : 'Faible',
|
|
summary: totalResults === 0 ?
|
|
'Aucune mention de gel des avoirs trouvée sur Bodacc' :
|
|
`${totalResults} mention(s) trouvée(s), ${highConfidenceResults.length} avec haute confiance`
|
|
};
|
|
}
|