10
6

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.

うるるをPuppeteerでスクレイピングしてみた

Last updated at Posted at 2019-12-20

こんにちは!
新卒2年目のKawamotoです!!

今回は自分が担当しているプロジェクトで愛用している,
Puppeteerを使ってスクレイピングします!
自社サービスの宣伝も兼ねて,
スクレイピングの対象は, うるるのコーポレートサイトにしました!

はじめに

この記事はうるる Advent Calendar 2019 21日目の記事です.

Puppeteerを勉強するなら下記の本が結構参考になりますよ!!
https://www.amazon.co.jp/dp/B07MJPM15V/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1

準備

本orWebを駆使して動くように準備!!

初期状態

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

(async () => {
  const browser = await puppeteer.launch({
    headless: false,
    slowMo: 50,
  });

  const page = await browser.newPage();

  await page.goto('https://www.uluru.biz');

  await browser.close();
})();

とりあえずTopページにアクセスできるようにした.

文字列の取得

自社サービスであるシュフティの説明文を取得する.
スクリーンショット 2019-12-08 0.20.07.png

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

(async () => {
  const browser = await puppeteer.launch({
    headless: false,
    slowMo: 50,
  });

  const page = await browser.newPage();

  await page.goto('https://www.uluru.biz/service/service_shufti');

  // セレクタを指定
  let shuftiServiceGuide=".entry-content .container-1140.relative p";

  // 要素を取得
  var data = await page.$eval(shuftiServiceGuide, item => {
      return item.textContent;
  });

  console.log(data);

  await browser.close();
})();

結果 :
とれた :clap:
スクリーンショット 2019-12-08 0.46.10.png

画像のダウンロード

自社サービスであるfondeskの画像を取得する.

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

// 画像ダウンロードに必要
const fs = require('fs');
const path = require('path');

(async () => {
  const browser = await puppeteer.launch({
    headless: false,
    slowMo: 50,
  });

  const page = await browser.newPage();

  await page.goto('https://www.uluru.biz/service/fondesk');

  // imgタグの取得
  const img = await page.$('.slick-slide.slick-current.slick-active img');

  // 取得したタグのsrc属性を取得
  const src = await img.getProperty('src');

  // JSHandleオブジェクトの内容をjsonValueで取り出す
  const targetUrl = await src.jsonValue();

  // URL形式で取得できたパスのファイル名部分を取り出す
  const filename = targetUrl.split('/').pop();

  // 直下に保存
  const localfilefullpath = path.join(__dirname, filename)
  const viewSource = await page.goto(targetUrl);
  fs.writeFile(localfilefullpath, await viewSource.buffer(), (error) => {
    if (error) {
      console.log(`error=${error}`)
      return;
    }
  });
  
  await browser.close();
})();

結果 :
とれた :clap:
スクリーンショット 2019-12-08 1.14.32.png

画面のキャプチャ

弊社の20新卒内定者のエンジニアが作成した21新卒採用サイトのTop画面を全画面キャプチャしてみる.

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

(async () => {
  const browser = await puppeteer.launch({
    headless: false,
    slowMo: 50,
  });

  const page = await browser.newPage();

  await page.goto('https://www.uluru.biz/recruit_newgrads/');

  // fullPageをtrueにすると全画面キャプチャ
  await page.screenshot({ path: 'fullpage.png', fullPage: true});

  await browser.close();
})();

結果 :
とれた :clap:
スクリーンショット 2019-12-08 19.57.26.png

弊社は21新卒大募集中です!!
https://blog.uluru.biz/entry/2019/11/05/154011

PDFを取得

弊社のIR情報を取得する.
別タブで開くPDFなので少々工夫が必要.(ヘッドレスモードにしなければ問題ない!)
https://github.com/puppeteer/puppeteer/issues/830

ここではaxiosを使用して取得する!

puppeteer.js
const puppeteer = require('puppeteer');
const fs = require('fs');
const axios = require('axios')

// PDFをダウンロードする関数
async function fetch(url, cookies = '') {
  const res = await axios.get(url, {
    headers: {
      Cookie: cookies,
      Accept: 'application/pdf'
    },
    responseType: 'arraybuffer'
  })
  return res.data
}

(async () => {
  const browser = await puppeteer.launch({
    // headlessモードにする
    headless: true,
    slowMo: 50,
  });

  const page = await browser.newPage();

  await page.goto('https://www.uluru.biz/ir/');

  // 2019.11.14のIR資料
  const img = await page.$('#dataList .irGroup dl:nth-child(1) dd a');
  const src = await img.getProperty('href');
  const targetUrl = await src.jsonValue();

  // cookieの取得
  const cookies = (await page.cookies())
        .map(c => `${c.name}=${c.value};`)
        .join(' ')

  const data = await fetch(targetUrl, cookies);

  fs.writeFileSync('./IR.pdf', new Buffer.from(data), 'binary');

  await browser.close();
})();

結果 :
とれた :clap:
スクリーンショット 2019-12-20 23.31.21.png

取得したファイルなどをS3に送る

バケットの用意や権限の調整は各自で🙇‍♂️

puppeteer.js

const puppeteer = require('puppeteer');
const axios = require('axios')
const AWS = require('aws-sdk');
const uuidv4 = require('uuid/v4')
const s3 = new AWS.S3();
const bucket = 'Hoge';

// PDFをダウンロードする関数
async function fetch(url, cookies = '') {
  const res = await axios.get(url, {
    headers: {
      Cookie: cookies,
      Accept: 'application/pdf'
    },
    responseType: 'arraybuffer'
  })
  return res.data
}

(async () => {
  const browser = await puppeteer.launch({
    headless: false,
    slowMo: 50,
  });

  const page = await browser.newPage();

  await page.goto('https://www.uluru.biz/ir/');

  // 2019.11.14のIP資料
  const img = await page.$('#dataList .irGroup dl:nth-child(1) dd a');
  const src = await img.getProperty('href');
  const targetUrl = await src.jsonValue();

  // cookieの取得
  const cookies = (await page.cookies())
      .map(c => `${c.name}=${c.value};`)
      .join(' ')

  const data = await fetch(targetUrl, cookies);

  const params = {
    Bucket: bucket,
    Key: uuidv4(),
    Body: data
  };

  await s3.putObject(params).promise();

  await browser.close();
})();

さいごに

Puppeteerを利用すると簡単にスクレイピングができます!
みなさんもWeb上に転がっている情報をPuppeteerでGETしちゃいましょう👍

明日は、アニさんによる記事です!
ご期待ください!

10
6
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
10
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?