【JavaScript】スクレイピングとは?仕組みと実装方法を初心者向けにわかりやすく解説

はじめに

スクレイピングという言葉に馴染みのない方でも、ウェブ上のデータを自動で取得することに興味を持ったことがあるかもしれません。
JavaScriptでスクレイピングを実現すると、普段ブラウザで実行している操作と同じ感覚でデータを取得できるようになります。

しかしスクレイピングは、ただコードを書いて動かすだけではありません。
ウェブページのHTML構造や動的なコンテンツの仕組みを理解していないと、思うようにデータを抽出できないことがあります。

そこでこの記事では、JavaScript を使ったスクレイピングの仕組みと実装手順を初心者の方にもわかりやすくまとめていきます。
実務での活用場面にも触れながら、具体的なコード例をあわせて解説していきますので、ぜひ最後までお読みください。

この記事を読むとわかること

  • スクレイピングの基本的な考え方
  • JavaScriptでスクレイピングを行うメリット
  • 実務での活用シーンと注意点
  • HTTPリクエストやDOM解析の具体的な方法
  • 動的ページを対象にしたスクレイピングの実装例

JavaScriptスクレイピングの基本とは?

スクレイピングとは、ウェブサイトから情報を取得して自動的にデータ化する技術を指します。
一般的には、HTMLの構造を解析して必要なテキストや画像などを抽出するケースが多いです。

ブラウザでページを開いて目視で確認する代わりに、プログラムがページの構造を読み取り、自動でデータを集めるわけです。
JavaScript はブラウザ上で動作させられるので、動的に生成される内容でも扱えるのが特徴といえます。

スクレイピングとは何か?

スクレイピングでは、主に以下のステップでデータを取得します。

  1. 対象のページにアクセスする
  2. ページのHTMLを取得する
  3. HTMLを解析して必要な要素を探す
  4. データを抽出し、整形する

たとえば商品ページの価格情報やレビューなどを大量に取得したい場合、スクレイピングは非常に便利です。
これらのステップをJavaScriptで実装すると、フロントエンドで使われる技術を活かしてスムーズにページ内容へアクセスできます。

JavaScriptでスクレイピングするメリット

JavaScript はウェブブラウザでの動作に最適化された言語です。
そのため、ブラウザが持つDOM操作機能を使ってページ内容を取得したり、クリックやフォーム送信などの動作を簡単に模倣できます。

一方で、Node.jsを利用するとサーバーサイドのJavaScript実行環境が手軽に作れるため、単純なHTTPリクエストから高度なスクレイピングまで幅広く対応しやすいです。
これは多くのパッケージが用意されていることもメリットの一つといえます。

JavaScriptでスクレイピングする実務での活用シーン

スクレイピングは、実務でも多様な分野で活用されています。
ウェブ上の公開情報を自動収集してビジネスに生かすケースは少なくありません。
ここではJavaScriptを使ったスクレイピングがどのように役立つか、具体的なシーンをいくつか見てみましょう。

価格情報の収集

ECサイトやオンラインショップの価格情報をまとめて収集し、相場調査を行うケースがあります。
商品データの一部として、商品名や在庫状況なども一緒に取得すると、より詳細な比較が可能になります。
JavaScriptのスクレイピングなら動的に表示される価格変更にも対応しやすいのが強みです。

データ収集と統合

あるサイトのリストページから詳細情報へのリンクを一つひとつたどり、それぞれのページの情報を取得する、といった処理を自動化できます。
たとえば求人情報や不動産情報を集めてデータベース化し、独自の分析を行うといった用途にも向いています。
人手で集めると膨大な時間がかかりますが、スクレイピングを使うと作業効率が大幅に向上します。

競合調査や市場分析

製品の特徴や口コミなどを定期的に収集すると、競合他社の動向をチェックできます。
また市場分析のためにSNSから特定のキーワードを含む投稿を収集するといった活用方法もあります。
JavaScriptはSNSのような動的サイトでも、ブラウザを操作する感覚で情報を取得できるため有利です。

環境準備の手順

JavaScriptでスクレイピングを始めるには、まずNode.jsをインストールしておくと便利です。
ブラウザ上のコンソールでも試せますが、大量のデータを扱ったりファイルに保存したりするのであれば、Node.js環境で作業を進めるほうが取り回しやすいでしょう。

Node.jsをインストール

公式サイトからインストーラーをダウンロードしてインストールします。
インストール後にターミナル(またはコマンドプロンプト)で node -v と入力すると、Node.jsのバージョンが表示されれば成功です。

スクレイピングツールのインストール

スクレイピングにはさまざまなツールやライブラリがあります。
たとえばHTTPリクエストを簡単に送るための axios や、DOM解析用に cheerio、動的ページに対処する場合は puppeteer などを使います。

以下のように、npmを使ってライブラリをインストールします。

npm install axios cheerio puppeteer

これらをすべて同時に入れることも可能です。
用途に合わせて選びましょう。

基本的なHTTPリクエストによるスクレイピング

スクレイピングの最も基本的なやり方は、HTTPリクエストでHTMLソースを取得し、そこから必要な情報を取り出す方法です。
単純な静的ページであれば、この方法だけでも十分にデータを収集できます。

fetchを使ったスクレイピング

ブラウザ上のJavaScriptには、 fetch 関数があります。
ウェブページのJSコンソールでも実行できるため、簡単なスクレイピングの試作をするには便利です。

fetch("https://example.com")
  .then(response => response.text())
  .then(html => {
    console.log(html);
    // ページのHTMLソースが表示される
  })
  .catch(err => {
    console.error("エラーが発生しました", err);
  });

このようにHTMLを取得して、文字列としてコンソールに出力できます。
ただしブラウザ側のCORS制限などで取得できない場合もあるため、実務ではNode.js環境を利用するケースが多いです。

Axiosを使ったスクレイピング

Node.js環境でHTTPリクエストを行う場合、 axios がよく使われます。
コード量が少なく、エラー管理もしやすいのが特徴です。

const axios = require("axios");

axios
  .get("https://example.com")
  .then(response => {
    const html = response.data;
    console.log(html);
  })
  .catch(err => {
    console.error("エラーが発生しました", err);
  });

こちらも返ってくるのは文字列のHTMLソースなので、後述するDOM解析用のツールと組み合わせて使用すると便利です。
ページ内の特定要素にアクセスしたい場合は、次のステップとしてHTML解析が必要になります。

HTMLの解析方法

取得したHTMLソースは、文字列そのものを眺めるだけでは必要な情報を抜き出すのが大変です。
DOMの構造を意識しながら要素をピンポイントで取り出すには、専用のツールを活用するのが効率的です。

DOM構造と要素の取得

DOM(Document Object Model)とは、HTML文書を木構造で表現したものです。
ブラウザ上では、 <div><p> といったタグに簡単にアクセスできますが、Node.js環境の場合は単純にHTMLを文字列で扱うだけでは難しい場面もあります。

そこで Cheerio のようなライブラリを使うと、Node.jsであってもDOM操作に似た感覚でタグを扱うことができます。
例えば $('.title') のように、クラス名や要素名を指定して抽出できるので便利です。

Cheerioを使ったDOM解析

Cheerioを使ったサンプルコードを少しだけ紹介します。
以下のコードでは、あるページの <h1> 要素を取得して表示しています。

const axios = require("axios");
const cheerio = require("cheerio");

axios
  .get("https://example.com")
  .then(response => {
    const $ = cheerio.load(response.data);
    const h1Text = $("h1").text();
    console.log("ページの見出し:", h1Text);
  })
  .catch(err => {
    console.error("エラーが発生しました", err);
  });

cheerio.load() にHTMLソースを渡すと、 $ オブジェクトが返ってきます。
あとは $ に対してCSSセレクタを使い、目的の要素を探すイメージです。
これによって、HTML上の要素のテキストや属性などが簡単に扱えるようになります。

JavaScriptで動的に生成されるページのスクレイピング

最近では、表示内容をJavaScriptが動的に書き換えるサイトが増えています。
その場合、HTTPリクエストで取得したソースを見ても、実際には中身が空っぽだったり、途中で書き換えられる情報があったりするのです。

こうした動的ページを対象にする場合は、Headlessブラウザ と呼ばれる仕組みを使うことがあります。
代表的なのが PuppeteerPlaywright などです。

PuppeteerやPlaywrightの活用

Puppeteerは、Google Chromeを操作するためのライブラリです。
ブラウザ上で実際にページを読み込み、JavaScriptが動作した後の状態まで再現したうえでHTMLを取得できます。

const puppeteer = require("puppeteer");

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

  // JavaScriptで動的に生成された内容も含めて取得
  const content = await page.content();
  console.log(content);

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

page.goto() でウェブページにアクセスし、ネットワーク通信が落ち着くまで待機すると、その間に動的なコンテンツが書き換えられた状態になります。
この仕組みによって、シングルページアプリケーション(SPA)のようなサイトでも、最終的なHTMLをきちんと取り出せるわけです。

実装例

ここからは、実際にJavaScriptでスクレイピングする際の例をもう少し詳しく見ていきましょう。
前述したように、静的ページの場合はHTTPリクエスト+DOM解析、動的ページの場合はHeadlessブラウザを使う方法が主流です。

Cheerioを使ったサンプルコード

Cheerioは、シンプルな構成のページをスクレイピングするのに向いています。
たとえば、以下のコードはあるサンプルサイトからニュースタイトルの一覧を取得する処理をイメージしたものです。

const axios = require("axios");
const cheerio = require("cheerio");

async function scrapeNewsTitles(url) {
  try {
    const response = await axios.get(url);
    const $ = cheerio.load(response.data);

    const titles = [];
    $(".news-title").each((index, element) => {
      const titleText = $(element).text();
      titles.push(titleText);
    });

    return titles;
  } catch (error) {
    console.error("スクレイピング中にエラーが発生しました", error);
    return [];
  }
}

// 実行例
(async () => {
  const newsTitles = await scrapeNewsTitles("https://example-news.com");
  console.log("取得したニュースタイトル:", newsTitles);
})();

$(".news-title") のように、CSSクラス名を指定することでまとめて要素を取得できます。
初心者でもDOM操作の感覚で扱えるので、静的ページのスクレイピングには非常に使いやすいです。

Puppeteerを使ったサンプルコード

次は動的なページにも対応可能なPuppeteerの例です。
以下のコードは、ボタンを自動クリックしてさらに表示される記事リストを読み込み、タイトルを取得するイメージで書かれています。

const puppeteer = require("puppeteer");

async function scrapeDynamicContent(url) {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  try {
    // ページにアクセス
    await page.goto(url, { waitUntil: "networkidle2" });

    // ボタンをクリックする(例:さらに読み込む)
    await page.click(".load-more-btn");
    // クリック後の処理が安定するまで待機
    await page.waitForSelector(".article-item");

    // 記事タイトルを取得する
    const titles = await page.$$eval(".article-item .title", elements => {
      return elements.map(el => el.textContent);
    });

    return titles;
  } catch (error) {
    console.error("スクレイピング中にエラーが発生しました", error);
    return [];
  } finally {
    await browser.close();
  }
}

// 実行例
(async () => {
  const data = await scrapeDynamicContent("https://example-dynamic.com");
  console.log("取得した記事タイトル:", data);
})();

JavaScriptによる動的操作をそのまま自動化しているので、ブラウザ上で人がクリックするのと似た形でデータを取得している点が特徴です。
このように、JavaScriptは静的・動的どちらのページでも比較的扱いやすいというメリットがあります。

スクレイピングの注意点

スクレイピングは非常に便利ですが、いくつか気をつけなければならないことがあります。
間違ったやり方をすると、利用規約違反やサーバーへの負荷などの問題が生じる恐れがあるのです。

法的リスク

ウェブサイトによっては、コンテンツの無断取得を禁止しているケースがあります。
利用規約にスクレイピングを禁じる文言がある場合は、取得行為そのものが違反となる可能性も否定できません。
また、個人情報の扱いについては関連する法令への配慮が必要な場合もあるため、事前の確認が必須です。

robots.txtと利用規約

多くのサイトには、 robots.txt というファイルが置かれていることがあります。
これは検索エンジンのクローラーなどがアクセスしてよいページや、アクセスを控えるべきページを指定するものです。
スクレイピングの際にも、このファイルに書かれた方針をできるだけ尊重することが望ましいです。

ただし、 robots.txt は法的拘束力があるわけではなく、マナーや負荷対策として機能していることが多いです。
利用規約で明確に禁止されているケースもあるので、合わせて確認しましょう。

連続リクエストによる負荷

大量のページを高速でリクエストすると、サーバーに過度な負荷をかける恐れがあります。
その結果、アクセス制限を受けたり、サイト運営者から警告を受けたりすることも考えられます。
実行時には一定の待機時間を入れるなどの配慮が必要です。

一度に何百回ものリクエストを連続して送ると、サーバーに大きな負荷がかかる恐れがあります。 処理速度を上げたい場合でも、ある程度のインターバルを設けるなどして慎重に進めるほうが安全です。

処理速度を向上させる方法

スクレイピングの規模が大きくなると、取得に時間がかかるようになります。
そこで、処理速度を向上させるための工夫も取り入れると良いでしょう。

同期と非同期処理

JavaScriptでは、非同期処理を活用して複数のリクエストを同時に処理することが可能です。
たとえば、 Promise.all() を使って複数のページを一度にリクエストし、結果をまとめて受け取る方法があります。

ただし、同時リクエストが多すぎるとサーバーに負荷をかけるので、適切な数に制限することが大切です。
p-limit のようなライブラリを使うと、同時実行数を制御するのも簡単になります。

過度なリトライの回避

エラーが出た場合にリトライする仕組みを組み込むと、多少の接続障害を補うことができます。
しかし、あまりにもリトライ回数が多いと結果的にリクエスト数が膨れ上がり、サーバーやネットワークに無駄な負荷がかかります。

このような場合は、リトライ間隔に待機時間を入れたり、リトライ上限を設定したりして、無制限にアクセスを繰り返さないようにする必要があります。

トラブルシューティング

スクレイピングをしていると、さまざまなトラブルに遭遇することがあります。
ここでは、代表的な問題と対処法を簡単に整理しておきます。

エラーが返る場合の対処

アクセス先からエラーコード(404、500など)が返ることは珍しくありません。
この場合はリトライする前に、本当にURLが正しいか、あるいは相手サイトが一時的にダウンしていないかを確認してください。
また、不審なアクセスと判断されて拒否されることもあるので、必要以上にリクエストを送っていないか見直すのも重要です。

文字化けの対処

スクレイピングの結果をコンソールに出力したら文字化けしていた、というケースもあります。
文字コードが想定と異なっている場合は、レスポンスヘッダを調べるか、サーバー側のエンコーディングを確認してください。
Cheerioを使った場合でも、受け取ったHTMLが正しく変換されていないと、テキストが乱れてしまいます。

ページの文字コードがUTF-8でない場合、追加の変換処理が必要になるかもしれません。 とはいえ、近年はUTF-8を使うサイトが増えているので、まずは取得したHTMLのメタタグやレスポンスヘッダを調べてみるとよいでしょう。

この記事を読むうえで理解しておきたい簡単な用語

スクレイピングでは、普段あまり意識していないウェブ技術の知識も必要になります。
最低限、次の用語だけでも押さえておくとスムーズに進められます。

HTTPリクエスト

ブラウザがウェブサイトにアクセスするときに送信する問い合わせのことです。
GET でページを取得したり、 POST でフォームを送信したりといった操作が行われます。

DOM

HTMLを構造化して表現するモデルです。
JavaScriptでは、DOMを通じてページ内の要素を取得・編集できます。
スクレイピングでも、DOM構造を意識すると欲しい情報を正確に抜き出せるようになります。

まとめ

ここまで、JavaScript を使ったスクレイピングの基本から実装方法、そして注意点まで一通り解説してきました。
静的サイトならHTTPリクエストでHTMLを取得し、 cheerio などのライブラリで解析するだけで十分に情報を抜き出せます。
一方、動的サイトでは Puppeteer のようなHeadlessブラウザを使ってブラウザ操作を再現すると、JavaScriptが生成したコンテンツも取得しやすくなるのです。

しかしスクレイピングは、その強力さゆえに法的リスクやサーバー負荷の問題などに気を配る必要があります。
サイトの利用規約や robots.txt を確認し、相手に迷惑がかからない形でデータを集めるのが大切です。

初心者の方は、まずは小規模なサイトの静的ページを対象に試してみると良いでしょう。
環境構築自体はNode.jsのインストールとライブラリの追加だけで済むので、ぜひ一度チャレンジしてみてください。
取り扱うデータはページ内要素のテキストから始めれば、DOM操作やJavaScriptの基本にも触れられて学びやすいはずです。

スクレイピングを通じて多様なウェブ情報を活用できるようになれば、独自の分析や業務改善に大いに役立つでしょう。
今回の記事が、皆さんの第一歩として何かしらの参考になれば幸いです。

JavaScriptをマスターしよう

この記事で学んだJavaScriptの知識をさらに伸ばしませんか?
Udemyには、現場ですぐ使えるスキルを身につけられる実践的な講座が揃っています。