
Puppeteerで複数のURL取得
Puppeteerで複数のURLを取得する際にfor ofを使用してループしてpage.gotoを使用すると1つずつ実行するため処理の完了が遅い。
複数のURLからdocument.titleなどのDOMの情報などを取得したい場合などはPromise.allを利用して同時(並列)にpage.gotoを実行したほうが処理時間が短くなる。※
※ headless: falseにしてpage.gotoでブラウザを表示して確認したい場合は逆にfor ofのほうが都合が良い。
for of 使用
const startTime = Date.now() const puppeteer = require('puppeteer') const DCL = {waitUntil: 'domcontentloaded'} const urls = [ 'https://yahoo.co.jp/', 'https://line.me/ja/', 'https://mixi.jp/', 'https://dena.com/jp/', 'http://gree.jp/', ]; (async() => { const browser = await puppeteer.launch() const titleList = [] for (const url of urls) { const page = await browser.newPage() await page.goto(url, DCL) const result = await page.evaluate(() => { return document.title }) titleList.push(result) await page.close() } console.log(titleList) await browser.close() console.log(Math.round((Date.now() - startTime) / 1000) + '秒') // => 6秒 })()
Promise.all 使用
const startTime = Date.now() const puppeteer = require('puppeteer') const DCL = {waitUntil: 'domcontentloaded'} const urls = [ 'https://yahoo.co.jp/', 'https://line.me/ja/', 'https://mixi.jp/', 'https://dena.com/jp/', 'http://gree.jp/', ]; (async() => { const browser = await puppeteer.launch() const promiseList = [] const titleList = [] urls.forEach(url => { promiseList.push((async() => { const page = await browser.newPage() const res = await page.goto(url, DCL) if (res.status() !== 200) return `${res.status()} ERROR` const result = await page.evaluate(() => { return document.title }) await page.close() return result })().catch(e => console.error(e))) }) await Promise.all(promiseList).then(vList => { vList.forEach(title => titleList.push(title)) }) console.log(titleList) await browser.close() console.log(Math.round((Date.now() - startTime) / 1000) + '秒') // => 3秒 })()
上記の処理時間はPCのスペックや回線速度によって変わるので注意。(Promise.allのほうが早く処理できることは変わらない)