Makery Blog

西麻布のクリエイティブラボ「Makery」でテクノロジーとアイデアをこねています。

WEBページをスクレイピングしたい。PUPPETEERで。

みなさまこんにちは
最近Adobe Project Aeroが気になっている花井です。
theblog.adobe.com


すみません。冒頭と関係なく、今回はPuppeteerを触ってみたのでその記事です。
スクレイピングとは取得したHTMLから任意の情報を抽出する技術・行為のことです。
今回紹介するPuppeteerはスクレイピングを行うnodeライブラリです。


Puppeteerとは?
PhantomJS や NightmareJS と同じ GUIを提供していないブラウザ(Headless Chrome)をNode.jsで操作しやすくしたライブラリです。
Chrome ベースで作成されており、提供元が Google公式のため開発・サポート終了などのリスクは少ないです。
また、JavaScriptエンジンを搭載したフルブラウザとしてのChrome(正確にはChromium)を内部的に呼び出してWebページをレンダリングしています。
そのため、Single Page Applicationのような、JSによって動的にHTMLが生成される場合でも問題なくレンダリングされ、画面キャプチャの作成やスクレイピング、その後のページに対してフィールドの選択や入力、結果の取得などを行うことができます。


ざっとこんな感じで書いてみました。以下、「弊社問い合わせフォームを入力しつつ画面キャプチャを撮るjs」です

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

(async () => {

// const browser = await puppeteer.launch({args: ['--no-sandbox', '--disable-setuid-sandbox']});
const browser = await puppeteer.launch({headless: false,slowMo: 300});
const page = await browser.newPage();

/*** 1 ***/
await page.goto('https://www.bbmedia.co.jp/system/contact/form/');
/* 画面をフルサイズで撮る */
await page.waitFor(3000);
await page.screenshot({path: 'test/bb/bb_form.png', fullPage: true});
console.log("############# open page");

/*** 2 ***/
await page.click('input[value="その他"]');
await page.type('input[name="user_name"]', 'BBテスト太郎');
await page.type('input[name="company_name"]', 'BBテスト社');
await page.type('input[name="contact_email"]', 'BBテストメール');
await page.type('input[name="contact_tel"]', 'BBテストでんわ');
await page.type('input[name="contact_url"]', 'BBテストURL');
await page.type('textarea[name="contact_content"]', 'BBテストBBテストBBテストBBテストBBテストBBテストBBテストBBテストBBテストBBテストBBテストBBテストBBテストBBテストBBテストBBテストBBテストBBテストBBテストBBテストBBテストBBテストBBテストBBテストBBテストBBテストBBテストBBテストBBテストBBテストBBテストBBテストBBテストBBテストBBテスト');

await page.waitFor(1000);
await page.screenshot({path: 'test/bb/INput.png', fullPage: true});
console.log('### input');


/*** 3 ***/
const submit = await page.$('input[type=submit]');
await submit.click();
await page.waitFor(1000);
await page.screenshot({path: 'test/bb/submit.png', fullPage: true});
console.log('### submit');


await browser.close();

assert(fs.existsSync('test/bb/bb_form.png'));
assert(fs.existsSync('test/bb/INput.png'));
assert(fs.existsSync('test/bb/submit.png'));

console.log('### DONE!!');
})();


↓画面キャプチャ



f:id:bbmedia:20180919190743p:plain
アクセス時キャプチャ


f:id:bbmedia:20180919190747p:plain
入力後画面キャプチャ


f:id:bbmedia:20180919190752p:plain
送信後画面キャプチャー

電話のエラーはわざとです。BBテスト太郎君の謎の問い合わせは自重しています。

また、実用的な使い方として、対象ページのリンク全てにおいて情報抽出&キャプチャ作成でしょうか。CMSで作った膨大なページ数があるサイトでも自動でチェックできます。


これをつかえば社内インフラ良くなるでしょうか?うまく活用できればと考えています。
今日のところは以上です。