node.js+Puppeteerによる動的ページのスクレイピング

最近のかっこいいWebとかだと、どういう仕組みかは分からないけど動的にデータが作られていて、htmlソースを見てもスクレイピングできないことがよくある。
西友のお墨付きブランドのページも、なかなか洗練されている(DeNAが作ったらしい?)。だけど商品情報をスクレイピングしようとしても、ソースコードには何も書いてないから、僕が得意な普通のVBAではうまくいかない。
西友 - プライベートブランド みなさまのお墨付き | SEIYU

あれこれ悩んで数か月、ようやく解決方法が見つかった。Puppeteerという、node.jsで動かせるChromeのヘッドレスブラウザを使うといい。これはすごくて、スクレイピング以外にもスクリーンショットなども取れる。
対象ページから抽出したいタグは、普通のChromeでInspectを選ぶことで見られると思う。node.jsはよく分からなかったけど、見よう見まねでDQNコードを作って一応動いている。非同期のところが癖があって難しかった。
はじめの一歩だから、多分すっごく汚いコードなんだろうけど、何個か作りながらnode.jsのこととかちゃんと理解できたらいいなと思う。

node.jsの最新バージョン(async対応)と、puppeteerが必要
node script.jsで実行


script.js

const fs = require('fs');
const assert = require('assert');
const puppeteer = require('puppeteer');

const len = 1500;
const sequential = new Array(len)
    .fill(1)
    .map((n, i) => n + i);
console.log(sequential.join(','));

loop(sequential);

async function loop(v) {
	for (let n of v) {
		await hoge(n);
	}
}

async function hoge(n){
	const browser = await puppeteer.launch();
	const page = await browser.newPage();
	await page.goto('http://●●.●●●●●.●●.jp/#item_' + n);
	console.log('http://●●.●●●●●.●●.jp/#item_' + n)
	//await page.screenshot({path: 'example.png'});

	const Names = await page.evaluate(() => {
		var array = [];
		var el = document.querySelector('div.bdr')
	        var node = el.querySelectorAll("p.name, p.price, p.area, div.dsc, div.rating");
		for(item of node){
	        	array.push(item.innerText);
	        }
	        return array;
	});
	browser.close();
	//assert(fs.existsSync('example.png'));
	fs.appendFile('writetest.txt', n + ',' + replaceElement(Names) + '\n', function (err) {
	    //console.log(err);
	});
}

function replaceElement(array) {
  for(var i=0; i<array.length; i++){
    array[i] = array[i].replace(/\r?\n/g,"");
  }
  return array;
}
(ご利用条件)当ブログは筆者の個人的見解を述べたものであり、筆者の所属する団体またはその公式見解とは一切関係がありません。当ブログは特定の金融商品の売買を推奨または勧誘またはあっせんするものではありません。当ブログにおいて情報提供の対価として閲覧者から金銭を徴収することはありません。当ブログの内容の正確性に関しては万全を期していますが、筆者は何らその保証を行うものではありません。投資は自己責任です。当ブログの内容をもとにして生じた損害について、筆者は一切の責任を負いません。