web-dev-qa-db-ja.com

パペットを使用して複数のURLをループでクロールする

私が持っています

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

これは私がやっていることです

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

これは、ページの読み込みを待たずにすべてのURLに非常に迅速にアクセスするようです(page.waitForを使用してみました)

根本的に間違ったことをしているのか、このタイプの機能が推奨/サポートされていないのかを知りたいだけです

17
ahhmarr

mapforEachreduceなどは、それらが繰り返し処理するイテレータの次の要素に進む前に、それらの中で非同期操作を待機しません。

非同期操作を実行しながらイテレータの各項目を同期的に実行する方法は複数ありますが、この場合、操作が完了するのを待つ通常のfor演算子を使用するのが最も簡単だと思います。

const urls = [...]

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

あなたが期待しているように、これは次々にURLを訪問します。 await/asyncを使用してシリアルに繰り返し処理することに興味がある場合は、次の回答を参照してください。 https://stackoverflow.com/a/24586168/791691

19
tomahaug

約束を無期限に待っていることがわかった場合、提案された解決策は以下を使用することです。

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;
}

これから参照されるように github issue

1
Neil