早速注意なのですが、現状暫定対応で凌いでおり個人的にしっくりしておりません。
なのでcoolな解決法がございましたら教えてください。
2018/06/13 追記
今は解消されていると思います!
暫定対応(飛ばしたい人はこちらから)
さて、困っていることはタイトルの通りだが、うだうだ文章に書くより実際にコードを載せたほうが早いと思うので下記が該当のものになる。
sample.js
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
]
});
process.on('unhandledRejection', (reason, p) => {
console.log(reason, p);
browser.close();
});
const page = await browser.newPage();
await page.goto('https://www.google.com/');
await page.type("#lst-ib", "puppeteer");
await page.click('input[name="btnK"]');
await page.waitFor('#rso > div > div > div:nth-child(1) > div > div.rc > h3 > a');
await page.waitFor('存在しない要素', {timeout: 1});
browser.close();
})();
で、上記を実行したときのコンソールがこちら
$ node sample01
Error: waiting failed: timeout 1ms exceeded
at Timeout.WaitTask._timeoutTimer.setTimeout (/home/operational_work/puppeteer/node_modules/puppeteer/lib/FrameManager.js:695:58)
at ontimeout (timers.js:475:11)
at tryOnTimeout (timers.js:310:5)
at Timer.listOnTimeout (timers.js:270:5) Promise {
<rejected> Error: waiting failed: timeout 1ms exceeded
at Timeout.WaitTask._timeoutTimer.setTimeout (/home/operational_work/puppeteer/node_modules/puppeteer/lib/FrameManager.js:695:58)
at ontimeout (timers.js:475:11)
at tryOnTimeout (timers.js:310:5)
at Timer.listOnTimeout (timers.js:270:5) }
エラーログとしてはtimeoutで落ちているのかはわかったのだが、どのwaitForで落ちているのかはわからないのでそれを解決したい。
試したこと
assert入れればいいんじゃない?
早速トライ
sample.js
const puppeteer = require('puppeteer');
const assert = require('assert');
(async () => {
const browser = await puppeteer.launch({
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
]
});
process.on('unhandledRejection', (reason, p) => {
console.log(reason, p);
browser.close();
});
const page = await browser.newPage();
await page.goto('https://www.google.com/');
await page.type("#lst-ib", "puppeteer");
await page.click('input[name="btnK"]');
await page.waitFor('#rso > div > div > div:nth-child(1) > div > div.rc > h3 > a');
assert(await page.waitFor('存在しない要素', {timeout: 1}));
browser.close();
})();
コンソール
$ node sample01
Error: waiting failed: timeout 1ms exceeded
at Timeout.WaitTask._timeoutTimer.setTimeout (/home/operational_work/puppeteer/node_modules/puppeteer/lib/FrameManager.js:695:58)
at ontimeout (timers.js:475:11)
at tryOnTimeout (timers.js:310:5)
at Timer.listOnTimeout (timers.js:270:5) Promise {
<rejected> Error: waiting failed: timeout 1ms exceeded
at Timeout.WaitTask._timeoutTimer.setTimeout (/home/operational_work/puppeteer/node_modules/puppeteer/lib/FrameManager.js:695:58)
at ontimeout (timers.js:475:11)
at tryOnTimeout (timers.js:310:5)
at Timer.listOnTimeout (timers.js:270:5) }
ダメだ変わらん…
バックトレース仕込めばいいんじゃない?
sample.js
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
]
});
process.on('unhandledRejection', (reason, p) => {
console.trace();
browser.close();
});
const page = await browser.newPage();
await page.goto('https://www.google.com/');
await page.type("#lst-ib", "puppeteer");
await page.click('input[name="btnK"]');
await page.waitFor('#rso > div > div > div:nth-child(1) > div > div.rc > h3 > a');
await page.waitFor('存在しない要素', {timeout: 1});
browser.close();
})();
コンソール
$ node sample01
Trace
at process.on (/home/operational_work/puppeteer/sample01.js:12:17)
at emitTwo (events.js:126:13)
at process.emit (events.js:214:7)
at emitPendingUnhandledRejections (internal/process/promises.js:94:22)
at runMicrotasksCallback (internal/process/next_tick.js:124:9)
at _combinedTickCallback (internal/process/next_tick.js:131:7)
at process._tickCallback (internal/process/next_tick.js:180:9)
あ、そうなるのね……。
暫定対応
色々ググってみたがようわからんとなり、どうしたか言うと……。
sample.js
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
]
});
process.on('unhandledRejection', (reason, p) => {
console.log('失敗したwaitFor:' + selector);
browser.close();
});
const page = await browser.newPage();
let selector;
const waitFor = x => {
selector = x;
return page.waitFor(selector, {timeout: 500});
};
await page.goto('https://www.google.com/');
await page.type("#lst-ib", "puppeteer");
await page.click('input[name="btnK"]');
await waitFor('#rso > div > div > div:nth-child(1) > div > div.rc > h3 > a');
await waitFor('存在しない要素');
browser.close();
})();
waitForのラッピング関数を作って、selectorをどんどん上書いて失敗したのをログに出した。
で、コンソール
$ node sample01
失敗したwaitFor:存在しない要素
一応、目的は達成したけどなんか腑に落ちにない……。
なので、アドバイス等を募集中です。