LoginSignup
1
0

More than 1 year has passed since last update.

Puppeteerでデータ取得

Last updated at Posted at 2022-03-10

やること

ログインがあるサイトのデータ取得

前提

以前作成した下記記事の環境からスタート

puppeteerインストール

yarn add puppeteer puppeteer-core

サイトに入る

puppeteer.ts

import puppeteer from "puppeteer"
import dotenv from "dotenv"

import { initLogger } from "../logger/index"

dotenv.config()
const { infoLogger, errorLogger } = initLogger("src/logger/index.ts")

type ScrapingData = () => Promise<void>
export const scrapingData: ScrapingData = async () => {
  const { URL } = process.env
  if (!URL) throw new Error("URLがありません")
  const browser = await puppeteer.launch({
    //開発時はヘッドレスモードオフで行う
    headless: false,
    args: ["--no-sandbox", "--disable-setuid-sandbox"],
  })
  const page = await browser.newPage()

  try {
    infoLogger("サイトに侵入開始")

    await page.setViewport({ width: 2000, height: 800 })
    await page.goto(URL, { waitUntil: "load" })

    //スクリーンショット
    await page.screenshot({ path: "test.png" })

    infoLogger("サイト侵入に成功")
    return Promise.resolve()
  } catch (error) {
    errorLogger("サイト侵入に失敗", { error })
    return Promise.reject(error)
  } finally {
    infoLogger("ブラウザクローズ開始")
    browser.close().then(() => infoLogger("ブラウザクローズ終了"))
  }
}

yarn run ts-node-dev src/puppeteer.ts

勝手にブラウザが立ち上がり、test.pngでそのページのスクリーンショットが撮れていればOK!

ログイン

puppeteer.ts

import puppeteer from "puppeteer"
import dotenv from "dotenv"

import { initLogger } from "../logger/index"

dotenv.config()
const { infoLogger, errorLogger } = initLogger("src/logger/index.ts")

type ScrapingData = () => Promise<void>
export const scrapingData: ScrapingData = async () => {
  const { URL, USERNAME, PASSWORD } = process.env
  if (!URL || !USERNAME || !PASSWORD) throw new Error("ログイン情報がありません")
  const browser = await puppeteer.launch({
    //開発時はヘッドレスモードオフで行う
    headless: false,
    args: ["--no-sandbox", "--disable-setuid-sandbox"],
  })
  const page = await browser.newPage()

  try {
    infoLogger("ログイン開始")

    await page.setViewport({ width: 2000, height: 800 })

    await page.goto(URL, { waitUntil: "load" })

    await page.type('input[name="user_name"]', USERNAME)
    await page.type('input[name="password"]', PASSWORD)

    await Promise.all([page.waitForNavigation({ waitUntil: "load" }), page.click('input[type="submit"]')])

    //スクリーンショット
    await page.screenshot({ path: "test1.png" })

    infoLogger("ログインに成功")
    return Promise.resolve()
  } catch (error) {
    errorLogger("ログイン失敗", { error })
    return Promise.reject(error)
  } finally {
    infoLogger("ブラウザクローズ開始")
    browser.close().then(() => infoLogger("ブラウザクローズ終了"))
  }
}
  • USERNAMEPASSWORDを追加
  • page.typeの中身はサイトの検証(Element)から確認
  • page.clickも同様

yarn run ts-node-dev src/puppeteer.ts

test1.pngでログイン後のスクリーンショットが撮れていればOK!

要素が取得できているか確認する方法

ブラウザのコンソールを開く

const a = document.querySelectorAll("要素"); 
console.log(a)

要素の部分に記載してみてログに入っていればOK!

データ取得

puppeteer.ts

import puppeteer from "puppeteer"
import dotenv from "dotenv"

import { initLogger } from "../logger/index"

dotenv.config()
const { infoLogger, errorLogger } = initLogger("src/logger/index.ts")

type ScrapingData = () => Promise<void>
export const scrapingData: ScrapingData = async () => {
  const { URL, USERNAME, PASSWORD } = process.env
  if (!URL || !USERNAME || !PASSWORD) throw new Error("ログイン情報がありません")
  const browser = await puppeteer.launch({
    //開発時はヘッドレスモードオフで行う
    headless: false,
    args: ["--no-sandbox", "--disable-setuid-sandbox"],
  })
  const page = await browser.newPage()

  try {
    infoLogger("ログイン開始")

    await page.setViewport({ width: 2000, height: 800 })

    await page.goto(URL, { waitUntil: "load" })

    await page.type('input[name="user_name"]', USERNAME)
    await page.type('input[name="password"]', PASSWORD)

    await Promise.all([page.waitForNavigation({ waitUntil: "load" }), page.click('input[type="submit"]')])

    const list = await page.$eval("要素", (value) => {
      return value.textContent
    })

    console.log(list)

    infoLogger("ログインに成功")
    return Promise.resolve()
  } catch (error) {
    errorLogger("ログイン失敗", { error })
    return Promise.reject(error)
  } finally {
    infoLogger("ブラウザクローズ開始")
    browser.close().then(() => infoLogger("ブラウザクローズ終了"))
  }
}
  • page.$evalの追加
  1. yarn run ts-node-dev src/puppeteer.ts

コンソールに取得したい文字が出力されればOK!
他にも取得の方法はありますが、こちらの記事を参考にして試行錯誤してみると良いです。

+a

app.ts

app.get("/", async (_req, res) => {
scrapingData()
res.end("Hello World")
})

puppeteer.tsの関数をappに入れることでまとめることができる

  • yarn dev
  • curl http://localhost:8080
    上記を実行するとデータ取得開始

自分の解釈

$:要素取得
$eval:コールバックで要素取得
$$:複数要素取得
$$eval:コールバックで複数要素取得

最後に

本当に人が操作しているみたいに動かすので、1つ1つの動きを実際に手で動かしてみるとコードが書きやすいです。また、目で確認するためにスクリーンショットを挟み込みながら進めていくことをオススメします!

参考文献

1
0
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
1
0