Help us understand the problem. What is going on with this article?

puppeteerでよく使うであろう処理の書き方

More than 1 year has passed since last update.

puppeteer
https://github.com/GoogleChrome/puppeteer/releases

puppeteerを触ってみて自分がよく使う書き方を載せたら
これから始めてみようかなって人に需要あるんじゃないかと書いてみます

Basic認証突破

const USERNAME = 'user';
const PASSWORD = 'passwd';
await page1.setExtraHTTPHeaders({
    Authorization: `Basic ${new Buffer(`${USERNAME}:${PASSWORD}`).toString('base64')}`
});

ページ移動

await page.goto("https://qiita.com/", {waitUntil: "domcontentloaded"});

第二引数のwaitUntilオプションなしで次にセレクタに関する処理を書くと
ページを読み込む前に処理が走ってセレクタを取得できずエラーになったりするので
DOM読み込み完了を待たせます

タブ切り替え

const page1 = await browser.newPage();
const page2 = await browser.newPage();
await page1.bringToFront();

2個タブ開いて1個目のタブに戻る

入力

await page.type("#loginid", "input");

id="loginid"の入力欄にinputって入力してくれます

セレクトボックスから選択

await page.select('select[name="birthday_month"]', '12');

value="12"のoption要素を選択します

クリック

page.click('a[href^="index.php?query="]');

正規表現も使えるので^=って書くと前方一致で探せます
index.php?query=から始まるhref属性を持つaタグをクリックしてくれます

フォーム送信

await page.evaluate(({}) => {
    $('input[name="mode"]').parent("form").submit();
},{});

<input type="hidden" name="mode" value="submit">
みたいな要素を含むformをsubmitしてくれます
id属性がないフォームが並んでたりするときは無理やりsubmitボタンをクリックさせるより
submitさせる方が便利だったりします

ページ遷移を待つ

page.click('a[href="index.php"]');
await page.waitForNavigation({timeout: 60000, waitUntil: "domcontentloaded"});

page.waitFor(3000)みたいに待つのはちょっとかっこ悪いのでページ遷移を検知させます
page.waitForNavigationの方だけawaitさせるのがポイントです

遷移を待つ その2

await page.click('a[href="login.php"]');
await page.waitFor('a[href="mypage.php"]', {timeout: 120000});

遷移先の要素が取得できるようになるまで待たせる、というやり方です
いっぱいリダイレクトしてある要素のあるページにたどり着く、みたいな時はこれですかね

CSSを操作

await page.evaluate(({}) => {
    $('#slider').css("display", "block");
},{});

アコーディオンとかはクリックさせて開くか、cssを直接いじるか
隠れてる入力欄に入力とかさせる分には困らないんですが
ヘッドレスモードオフで画面見ながら動かしたい時はこうやって表示させたり

valueの取得

var login_id = await page.$eval('input[name="login_id"]', el => el.value);

readonlyの入力欄から値を取ったりhidden属性のinput要素から値を取るにはこれ

要素内のテキストを取得

var data = await page.$eval('.classname', item => {
    return item.textContent;
});

<div class="classname"></div>とかで囲まれているテキストを取る時はこれ

API一覧見るともっともっとたくさんありますが
この辺の書き方使えばそれなりに事足りるかなと

rh_taro
timee
日本の労働力の減少を若者の働き方改革で解決します。好きな時に好きなだけ働けるプラットフォームタイミーを作り、人々が好きなことをできる世界を実現します。
https://timee.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away