web-dev-qa-db-fra.com

Analyser plusieurs URL dans une boucle à l'aide de puppeteer

J'ai 

urls = ['url','url','url'...]

c'est ce que je fais 

urls.map(async (url)=>{
  await page.goto(`${url}`);
  await page.waitForNavigation({ waitUntil: 'networkidle' });
})

Cela semble ne pas attendre le chargement de la page et visiter toutes les URL assez rapidement (j'ai même essayé d'utiliser page.waitFor) 

je voulais juste savoir si je fais quelque chose de fondamentalement faux ou que ce type de fonctionnalité n'est pas conseillé/pris en charge 

12
ahhmarr

map, forEach, reduce, etc. n'attend pas l'opération asynchrone en leur sein avant de passer à l'élément suivant de l'itérateur sur lequel ils effectuent une itération.

Il existe plusieurs façons de parcourir chaque élément d'un itérateur de manière synchrone lors d'une opération asynchrone, mais la solution la plus simple consiste à utiliser simplement un opérateur for normal, qui attend que l'opération se termine.

const urls = [...]

for (let i = 0; i < urls.length; i++) {
    const url = urls[i];
    await page.goto(`${url}`);
    await page.waitForNavigation({ waitUntil: 'networkidle' });
}

Ce serait visiter une URL après l'autre, comme vous l'attendez. Si vous êtes intéressé par une itération en série de wait/async, vous pouvez jeter un coup d'œil à cette réponse: https://stackoverflow.com/a/24586168/791691

15
tomahaug

Si vous constatez que vous attendez votre promesse indéfiniment, la solution proposée consiste à utiliser les éléments suivants:

const urls = [...]

for (let i = 0; i < urls.length; i++) {
    const url = urls[i];
    const promise = page.waitForNavigation({ waitUntil: 'networkidle' });
    await page.goto(`${url}`);
    await promise;
}

Comme indiqué dans cette question github

0
Neil