J'ai un tableau contenant des objets que je veux parcourir pour effectuer des appels axios et manipuler la réponse avec des fonctions. Malheureusement, la sortie finale est un tableau contenant plusieurs tableaux imbriqués avec le même objet répété, qui contient uniquement les résultats du premier élément du tableau des journaux.
const journaux= [{
"name": "CNN",
"address": "https://edition.cnn.com/specials/world/cnn-climate",
"base": "https://edition.cnn.com"
},
{
"name": "The Guardian",
"address": "https://www.theguardian.com/environment/climate-crisis",
"base": "https://www.theguardian.com"
}, etc...]
// Initialiser une variable globale pour les résultats
let articles = [];
// Fonction pour supprimer les doublons, obtenir une image si présente et regrouper les données
function stockerDonnees(element, base, name) {
const results = [];
element.find("style").remove();
const title = element.text();
const urlRaw = element.attr("href");
const url =
urlRaw.includes("www") || urlRaw.includes("http") ? urlRaw : base + urlRaw;
// Vérifier les URL en double
if (tempUrls.indexOf(url) === -1) {
// Vérifier les liens des médias sociaux et les ignorer
if (!exceptions.some((el) => url.toLowerCase().includes(el))) {
tempUrls.push(url);
// Obtenir l'image si enfant de la balise d'ancre
const imageElement = element.find("img");
if (imageElement.length > 0) {
// Obtenir l'attribut src de l'élément image
results.push({
title,
url,
source: name,
imgUrl: getImageFromElement(imageElement),
});
} else {
results.push({
title,
url: url,
source: name,
});
}
}
}
return results;
}
// Fonction Cheerio
function getElementsCheerio(html, base, name, searchterms) {
const $ = cheerio.load(html);
const termsAlso = searchterms.also;
const termsOnly = searchterms.only;
const concatInfo = [];
termsAlso.forEach((term) => {
$(`a:contains("climate"):contains(${term})`).each(function () {
const tempData = stockerDonnees($(this), base, name);
tempData.map((el) => concatInfo.push(el));
});
});
termsOnly.forEach((term) => {
$(`a:contains(${term})`).each(function () {
const tempData = stockerDonnees($(this), base, name);
tempData.map((el) => concatInfo.push(el));
});
});
return concatInfo;
}
// API
app.get("/news", (req, res) => {
// Chaîne de requête
const query = checkForQuery(req);
const wordsToSearch = query ? verifyQuery(query) : "";
Promise.all(
journaux.map(({ name, address, base }) =>
axios
.get(address, {
headers: { "Accept-Encoding": "gzip,deflate,compress" },
})
.then((res) => {
const html = res.data;
console.log({ name, address, base });
const scrappedElements = getElementsCheerio(
html,
base,
name,
wordsToSearch
);
scrappedElements.map((item) => articles.push(item));
return articles;
})
)
).then((articles) => {
res.json(articles);
});
});
Lorsque je connecte la boucle, je vois qu'elle se déroule correctement, cependant les mêmes deux articles récupérés du premier journal apparaissent également pour tous les autres:
console.log / résultat:
{
name: 'CNN',
address: 'https://edition.cnn.com/specials/world/cnn-climate',
base: 'https://edition.cnn.com'
}
[{title: article1,
url: article1,
source: article1,
imgUrl: article1},
{title: article2,
url: article2,
source: article2,
imgUrl: article2}]
{
name: 'The Times',
address: 'https://www.thetimes.co.uk/environment/climate-change',
base: 'https://www.thetimes.co.uk'
}
[{title: article1,
url: article1,
source: article1,
imgUrl: article1},
{title: article2,
url: article2,
source: article2,
imgUrl: article2}]
etc...
Comment puis-je corriger cela? Pourquoi même si le nouvel objet contenant les informations d'un autre journal passe, il collecte toujours les mêmes articles du premier?
Toute assistance est grandement appréciée. Je suis un développeur frontend, je fais cela à des fins d'apprentissage et je comprends que je pourrais manquer de certaines connaissances de base qui pourraient éviter ce problème stupide. Merci d'avance!