0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

React.jsでスクレイピングする方法

Posted at

React.jsはフロントエンドのライブラリであるため、スクレイピングを行う際にはCORS(クロスオリジン制約)や適切なデータ取得方法について理解することが重要です。

React.jsでスクレイピングをする際の問題点

React.jsはフロントエンドの技術なので、通常のバックエンドで行うスクレイピングとは異なり、いくつかの制約があります。

CORSの制約

ブラウザ上でスクレイピングを行う場合、異なるオリジン(ドメイン)からデータを取得しようとするとCORS制約によりブロックされることがあります。

Javascriptによるレンダリング

多くのWebサイトは、Javascriptを使ってデータを非同期にロードしているため、単純なfetchではHTMLにデータが含まれていないケースが多いです。

例えば、以下のページが React.js や Vue.js で動的にデータを読み込む場合、普通のHTTPリクエストではデータを取得できません。

<div id="app">
   <p>Loading...</p>
</div>

React.jsがデータを読み込んだあと、DOMが変更されてappの中にデータが入ります。しかし、通常のfetchではjavascriptが実行される前の状態しか取得できません。

解決策①

CORSの制約を回避するために、バックエンド(サーバー)を用意し、フロントエンド経由でリクエストを送る方法です。

①フロントエンド(React.js)は、自分のサーバー(Node.js/Expressなど)にリクエストを送る
②サーバー側がfetch()やaxiosを使い、外部のwebサイトからデータを取得する
③React.jsはサーバーからのレスポンスを受け取る

⭐️Node.js+Expressのサーバーを作る

const express=require('express');
const axios = require("axios");
const cors = require("cors");

const app = express();
const PORT = 3001;

// CORSを許可
app.use(cors());

app.get("/proxy", async (req, res) => {
    try {
        const response = await axios.get("https://example.com/data");
        res.json(response.data);
    } catch (error) {
        res.status(500).json({ error: "データ取得に失敗しました" });
    }
});

app.listen(PORT, () => console.log(`サーバー起動: http://localhost:${PORT}`));

⭐️React.js側でデータを取得

import { useEffect, useState } from "react";

const Scraper = () => {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch("http://localhost:3001/proxy")
      .then(response => response.json())
      .then(result => setData(result))
      .catch(error => console.error("Error:", error));
  }, []);

  return (
    <div>
      <h1>スクレイピング結果</h1>
      {data ? <pre>{JSON.stringify(data, null, 2)}</pre> : <p>読み込み中...</p>}
    </div>
  );
};

export default Scraper;

メリット

・CORSの制約を回避することができる(フロントエンドは自分のサーバーを経由するので、外部のサイトには直接アクセスしない)
・Webサイト側がAPIを提供していない場合でもデータを取得することができる

デメリット

・サーバーをセットアップする必要がある
・サーバーの負荷が増える

解決策②:ヘッドレスブラウザ(Puppeteer)を利用する

普通のfetch()では、Javascriptで動的にレンダリングされるページのデータを取得することはできない。そのため、Puppeteerというツールを使用してブラウザを自動操作しながらデータを取得する必要がある。

Puppeteerとは?

Puppeteerは、Google Chromeをプログラムで自動操作するためのツールです。
・Javascriptで描画されたページでもデータを取得することができる
・ログインが必要なサイトでも操作できる

Puppeteerでスクレイピングを行う

const puppeteer = require("puppeteer");

const scrapeData = async () => {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto("https://example.com");

    const data = await page.evaluate(() => {
        return document.querySelector("h1").innerText;
    });

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

scrapeData().then(console.log);

メリット

・Javascriptでレンダリングされるページでもデータを取得できる
・フォームの送信やページのスクロールなどブラウザの操作が可能

デメリット

・axiosやfetch()に比べて動作が重い(ブラウザを起動するため)
・サーバー環境によってはセットアップが必要

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?