4
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ひとりでAdvent Calendar 2019

Day 17

node.js スクレイピング

Last updated at Posted at 2019-12-16

スクレイピングとはプログラミングを使ってwebサイトから情報を取得する方法である。

スクレイピングは基本2種類あって、requestを送る方法とheadless browserを使ってbrowserを動かす方法の二つである。
requestを送る方法は処理自体は軽いが、Vue.jsやReact.jsを使ったSPAだと取得が難しい。
headless browserを使う方法は処理は重いが、SPAでも取得が可能。

テスト用途で使う時は、もう少しきちんと使うべきかもしれないが
スクレイピング用途で使う時はclickとtype以外はevaluate(javascript実行)のゴリ押しでいい。

参考URL Puppeteer.jsのgithub
https://github.com/puppeteer/puppeteer

npm init
npm install puppeteer
npm install cheerio

の3つをインストールする。
puppeteerはheadless browser
cheerioは取得したhtmlをjqueryライクで加工できるパーサーである。

###起動

下記例はgithubに載っている例を少し改良したものである。
launch関数でbrowserを作成。この時、headless:falseにしてあげることでブラウザを出しながら動かせる。
newPage関数でpageを作成。
goto関数でそのページに遷移。
close関数はbrowserを閉じるので、一旦コメントアウトしておく。

index.js
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({headless:false});
  const page = await browser.newPage();
  await page.goto('https://example.com');
  //await browser.close();
})();

###スクリーンショット

page.screenshot関数は現在ページのスクリーンショットを撮る。
pathのところに画像を保存。

index.js
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({headless:false});
  const page = await browser.newPage();
  await page.setViewport({width:800, height:600});
  await page.goto('https://example.com');
  await page.screenshot({path:"test.jpg"});
  
  //await browser.close();
})();

###htmlの取得

直接htmlを取得することができない。
セレクターで情報を取得した後、evaluateで(javascript)実行してあげないといけない。

index.js
const puppeteer = require('puppeteer');
const cheerio = require('cheerio');

(async () => {
  const browser = await puppeteer.launch({headless:false});
  const page = await browser.newPage();
  await page.setViewport({width:800, height:600});
  await page.goto('https://example.com');
  const bodyHandle = await page.$('body');
  const html = await page.evaluate((body) => body.innerHTML, bodyHandle);
  const $ = cheerio.load(html);
  var h1 = $('h1');
  console.log(h1.html());
  //await browser.close();
})();

###クリックして遷移する。

goto時、waitUntilオプションがないとすぐセレクターを使うとエラーが起こってしまう。
クリック時はwaitForNavigationと一緒に使ってあげないとエラーが出ることもある。
クリックの中身はセレクター。

index.js
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({headless:false});
  const page = await browser.newPage();
  await page.goto('xxxxxxxx', {waitUntil:'domcontentloaded'});

  await Promise.all[
      page.waitForNavigation(),
      page.click('yyyyyy')
  ];
  //await browser.close();
})();

###入力

index.js
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({headless:false});
  const page = await browser.newPage();
  await page.goto('xxxxxxxxxxx', {waitUntil:'domcontentloaded'});

  await page.type('yyyyyyyyyyy', "testtest");
  //await browser.close();
})();

###待機

page.WaitFor関数でミリ秒待つ。

index.js
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({headless:false});
  const page = await browser.newPage();
  await page.goto('xxxxxxx', {waitUntil:'domcontentloaded'});
  await page.waitFor(3000);
  //await browser.close();
})();
4
8
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
4
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?