LoginSignup
23
10

More than 3 years have passed since last update.

Puppeteerを使ってスクレイピングする時に個人的にはまったポイントのメモ

Last updated at Posted at 2020-01-28

概要

Puppeteerを使用してヘッドレスブラウザとしてウェブスクレイピングを行う時に、個人的に詰まった点のメモです。

前提

Mac OS v10.15.2(19C57)
VSCode 1.41.1
node v12.14.1
Puppeteer 2.1.0

その1 コンソール出力ができない

問題

page.evaluateを使うことで、ページ読み込み後にブラウザ内で任意のスクリプトを実行してHTMLの解析などが可能ですが、デバッグ用にconsoleを仕込んでも何も表示されません。


  // 初期化処理
  const browser = await puppeteer.launch({
    headless: true,
    args: ['--no-sandbox', '--disable-setuid-sandbox']
  });
  const page = await browser.newPage();

  // 指定のURLのページを開く
  await page.goto('https://hoge.hoge.hoge');

  // ブラウザ内でスクリプトを実行
  const result = await page.evaluate(() => {
    // ここでコンソールを出力しても何も表示されない
    console.log('eval start');
    // do something
  });

解決策

pageに対して、consoleイベントを予め登録し、イベント呼び出し処理内でconsoleで書き込みを行います。
page.evaluate内でconsoleを実行するとこのイベントが発火されてconsole出力がされるようになります。


  const page = await browser.newPage();
  // コンソールイベントを登録
  page.on('console', msg => {
    for (let i = 0; i < msg._args.length; ++i)
      console.log(`${i}: ${msg._args[i]}`);
  });
  // 指定のURLのページを開く
  await page.goto('https://hoge.hoge.hoge');

  // ブラウザ内でスクリプトを実行
  const result = await page.evaluate(() => {
    console.log('eval start');
    // do something
  });

その2 querySelectorAllで取り出した結果が空のオブジェクトになる

問題

page.evaluate内でquerySelectorを使ってHTML要素を出力しようとするが、正しく値が取れない。


    const result = await page.evaluate(() => {
      const dataList = [];
      // hogeクラスタグ配下のaタグを全て取得
      const nodeList = document.querySelectorAll('.hoge > a');
      // 内部のhtmlを出力
      nodeList.forEach(_node => {
        dataList.push(_node.innerText);
      });
      return dataList;
    });

    // 出力は空文字になる ["", "", ""]
    console.log(result);

解決策

querySelectorAllで取り出した値は配列になっていない為、Array.fromで配列に変換した後に列挙を行う。


    const result = await page.evaluate(() => {
      const dataList = [];
      // Array.fromで配列に変換
      const nodeList = Array.from(document.querySelectorAll('.hoge > a'));
      // 内部のhtmlを出力
      nodeList.forEach(_node => {
        dataList.push(_node.innerText);
      });
      return dataList;
    });

    console.log(result);

最後に

個人的にPuppeteer使用中にはまった点を書きました。
Puppeteer自体は直感的で便利なのですが、思いがけないところではまって時間を使ってしまいしました。
(マニュアル等をしっかり読まず使えしまう事の弊害かもしれませんが。)

23
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
10