Pupeteerでクローリング処理を作成した時の注意事項として、
全ての処理が終了した時にbrowser.close()
を呼び出さないと処理が終了しません。
//ページ内のatagのhrefを全部取得
async function getAtagHref(url) {
let outputs = [];
const puppeteer = require('puppeteer');
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(url, {waitUntil: "domcontentloaded"});
//ここでエラーが発生して終了
throw new Error('無理やりエラー!');
outputs = await page.$$eval('a', anchors => anchors.map(anchor => anchor.href));
await browser.close();
return outputs;
}
function main() {
try {
return getAtagHref('https://qiita.com/');
} catch (e) {
console.log(e);
//なんかクローリングがうまく行かなかったらから配列を返して終了してほしい
return [];
}
}
main()
上記javascriptをcliで実行しても処理は永久に終わりません。
CLIで使う分には Ctrl+C で良いのですが、
AWS Lambda や バッチ処理に組み込むときはこれだと困ってしまいます。
かといって、
await page.goto(url, {waitUntil: "domcontentloaded"})
.catch(async()=>await browser.close());
outputs = await page.$$eval('a', anchors => anchors.map(anchor => anchor.href))
.catch(async()=>await browser.close());
とか一々await ゴニョゴニョ().catch(async()=>await browser.close())
書くのも面倒だし、pupeteer以外で例外が発生したらやっぱり処理が終わらないので、
try~catch~finally 構文を使って確実にbrowser.close()
を呼び出すようにしましょう。
//ページ内のatagのhrefを全部取得
async function getAtagHref(url) {
const puppeteer = require('puppeteer');
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.goto(url, {waitUntil: "domcontentloaded"});
return await page.$$eval('a', anchors => anchors.map(anchor => anchor.href));
} catch(e) {
// 何かしらエラー処理
// 呼び出し元でcatchするのであればここのcatchは不要
throw e;
} finally {
//例外が発生しても発生しなくてもここは必ず通る
await browser.close();
}
}