質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

6214閲覧

Puppeteerで要素が存在するかチェックする方法

masahiro.o

総合スコア16

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2018/04/26 09:06

Node.jsでpuppeteerを使用してChromeの操作を自動化するJavaScriptを書いています。

例えばURL「https://www.example.com/」を表示し、idがbtn-nextのボタンを押したとき
遷移先のページでidがsuccessの要素が表示れたらidがbtn-submitのリンクをクリックするという処理の場合
以下のソースでうまくいきます。

JavaScript

1const puppeteer = require('puppeteer'); 2 3puppeteer.launch({ 4 headless: false, 5}).then(async browser => { 6 const page = await browser.newPage(); 7 8 await page.setViewport({ width: 1200, height: 800 }); 9 await page.goto('https://www.example.com/'); 10 await page.click('#btn-next'); 11 12 await page.waitForSelector('#success'); 13 14 await page.click('#btn-submit'); 15 16 17 browser.close(); 18 19}); 20

例えば、idがsuccessというのは通常パターンでは表示されるが、混雑時は表示されず
エラーページが表示されてしまう場合、エラーページが表示された場合はトップページに戻って
もう一度idがbtn-nextのボタンを押すような処理を行いたいです。

イメージとしては以下のような感じなのですが当然うまくいきません。

JavaScript

1 while(true){ 2 var item = page.$('#success'); 3 if (item != undefined) 4 { 5 break; 6 } 7 else 8 { 9 await page.goto("https://www.example.com/"); 10 await page.click('#btn-next'); 11 } 12 }

async/awaitを理解できていないのだと思いますが、ヒントだけでもご教示頂けると幸いです。
よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

await page.click('#btn-next') した直後に page.$('#success') で値を取得しようとしても、ページの遷移が完了する前なので上手く行かず、 page.waitForNavigation() を使ってページ遷移を待つ必要があるんじゃないかと思います。

それと page.$('#success') の戻り値は Promise 型なので、同期的に書く場合は await が必要です。

私なら下記のような感じで実装します。

js

1const puppeteer = require('puppeteer'); 2 3const sleep = msec => new Promise(resolve => setTimeout(resolve, msec)); 4 5const submitOnPage = async ({ page, interval, times }) => { 6 await page.goto('https://www.example.com/'); 7 8 const navigationPromise = page.waitForNavigation(); 9 await page.click('#btn-next'); 10 await navigationPromise; // クリック後にページ遷移を待つ 11 12 // #success の存在をチェック 13 const isLoadingSucceeded = await page.$('#success').then(res => !!res); 14 15 if (isLoadingSucceeded) { 16 await page.click('#btn-submit'); 17 } else if (times > 1 || times === -1) { 18 // インターバルを設ける 19 await sleep(interval); 20 // 再度試行 21 submitOnPage({ page, interval, times: Math.max(times - 1, -1) }); 22 } else { 23 throw new Error('繰り返し試行したけどダメでした…'); 24 } 25}; 26 27puppeteer 28 .launch({ 29 headless: false, 30 }) 31 .then(async browser => { 32 const page = await browser.newPage(); 33 34 await page.setViewport({ width: 1200, height: 800 }); 35 36 // インターバル2秒で最大10回試行する (times: -1 で無限に試行) 37 await submitOnPage({ page, interval: 2000, times: 10 }); 38 39 browser.close(); 40 }); 41

投稿2018/04/27 20:59

yhg

総合スコア2161

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

masahiro.o

2018/04/29 06:41

ありがとうございました。 やりたい事が実現できました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問