ホームページ > ウェブフロントエンド > jsチュートリアル > 無限スクロールでページからデータをスクレイピングする方法

無限スクロールでページからデータをスクレイピングする方法

Mary-Kate Olsen
リリース: 2025-01-03 12:41:08
オリジナル
798 人が閲覧しました

さらに多くのコンテンツを表示するために「ボタンをクリックする」などのアクションを必要とする Web ページに遭遇したことがありますか?このようなページは、ユーザーの操作に基づいてより多くのコンテンツを読み込むため、「動的 Web ページ」と呼ばれます。対照的に、静的 Web ページでは、ユーザーのアクションを必要とせずに、すべてのコンテンツが一度に表示されます。

動的ページからコンテンツをスクレイピングすることは、ボタンをクリックして追加の非表示コンテンツにアクセスするなど、ユーザー操作をシミュレートする必要があるため、困難を伴う場合があります。このチュートリアルでは、[さらに読み込む] ボタンを使用して無限スクロールを使用して Web ページからデータをスクレイピングする方法を学びます。

前提条件

このチュートリアルを進めるには、以下が必要です:

  • Node.js: 最新バージョンよりも安定した「LTS」(Long Time Support) タグが付いたバージョンをインストールします。
  • Npm: これは、パッケージのインストールに使用されるパッケージ マネージャーです。幸いなことに、「npm」は Node.js とともに自動的にインストールされるため、作業が大幅に高速化されます。
  • Cheerio: HTML の解析用
  • Puppeteer: これを使用してヘッドレス ブラウザを制御します。
  • Scraper を構築するための IDE: Visual Studio Code などのコード エディターを入手できます。

さらに、HTML、CSS、JavaScript の基本を理解している必要があります。 Chrome などの Web ブラウザも必要です。

プロジェクトを初期化する

新しいフォルダーを作成し、コード エディターで開きます。コードエディターで「ターミナル」タブを見つけて、新しいターミナルを開きます。 Visual Studio Code を使用してそれを見つける方法は次のとおりです。

How to Scrape Data from a Page with Infinite Scroll

次に、ターミナルで次のコマンドを実行して、このビルドに必要なパッケージをインストールします。

$ npm install cheerio puppeteer
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

コード エディターでプロジェクト フォルダー内に新しいファイルを作成し、dynamicScraper.js という名前を付けます。

素晴らしい仕事です、相棒!

ページのコンテンツへのアクセス

Puppeteer は、ヘッドレス Chrome ブラウザを制御できる強力な Node.js ライブラリであり、Web ページとの対話に最適です。 Puppeteer を使用すると、URL を使用して Web ページをターゲットにし、コンテンツにアクセスし、そのページからデータを簡単に抽出できます。

このセクションでは、ヘッドレス ブラウザを使用してページを開き、コンテンツにアクセスし、そのページの HTML コンテンツを取得する方法を学びます。このチュートリアルの対象 Web サイトはここにあります。

: すべてのコードは、dynamicScraper.js 内に記述する必要があります。

まず、require() Node.js 組み込み関数を使用して Puppeteer をインポートします。これは、コア モジュール、サードパーティ ライブラリ (Puppeteer など)、またはカスタム モジュール (ローカル JS ファイルなど) のモジュールをロードするのに役立ちます。

$ npm install cheerio puppeteer
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

次に、ターゲット URL を保存するための変数を定義します。これを行うことは必須ではありませんが、コード内のどこからでもこのグローバル変数を参照するだけで済むため、コードがすっきりします。

const puppeteer = require('puppeteer');
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

次のステップは、ヘッドレス ブラウザを起動し、ターゲット ページの HTML コンテンツを取得する関数を作成することです。処理を大幅に高速化するには、Immediately Invoked Function Expression (IIFE) メソッドを選択する必要があります。

try-and-catch ブロックを使用して非同期 IIFE を定義します。

const url = 'https://www.scrapingcourse.com/button-click';
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

: このチュートリアル セグメントのコードはすべて try ブロック内に記述する必要があります。

IIFE 内で、Puppeteer の新しいインスタンスを作成し、インタラクション用の新しいページを開きます。

launch メソッドを使用して Puppeteer ライブラリの新しいインスタンスを起動し、それにヘッドレス モードを渡します。ヘッドレス モードは true または false に設定できます。ヘッドレス モードを true に設定すると、Puppeteer の起動時にヘッドレス ブラウザーが表示されなくなりますが、false に設定するとブラウザーが表示されます。

Puppeteer を起動した後、ヘッドレス ブラウザーで新しいタブを開くトリガーとなる newPage メソッドも呼び出します。

(async () => {
    try {
        // Code goes here
    } catch (error) {
        console.error('Error:', error.message);
    }
})();
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

ここで、newPage メソッドをクエリして期待される URL をターゲットにし、page.goto メソッドを使用してその Web サイトをこの新しいタブで開きます。さらに、ページに重要なリソース (画像や JS など) がすべて読み込まれている場合にのみ、Puppeteer がページの操作とデータの抽出の準備ができているとみなされるようにする必要があります。

ページの準備が整っていることを確認するために、Puppeteer は waitUntil と呼ばれるオプションを提供します。このオプションは、ページをロードするためのさまざまな条件を定義するさまざまな値を受け取ることができます。

  • load: これは、HTML ドキュメントとそのリソース (画像、CSS、JS など) がロードされた後に発生するロード イベントが発生するのを待ちます。ただし、これは、load イベントの後に読み込まれる追加の JavaScript レンダリング コンテンツを考慮していない可能性があります。

  • domcontentloaded: これは、最初の HTML が解析されるとトリガーされる DOMContentLoaded イベントを待機します。ただし、これは外部リソース (画像や追加の JS など) が読み込まれる前に読み込まれます。

  • networkidle2: アクティブなネットワーク リクエスト (進行中の HTTP リクエスト (画像、スクリプト、その他のリソースのロードなど)) が 2 つ以下になるまで 500 ミリ秒待機します。この値は、小規模で継続的なリクエストを行うが、メイン コンテンツには影響を与えないページを扱う場合に推奨されます。

// Launch Puppeteer
const browser = await puppeteer.launch({ headless: false }); // Headless mode
const page = await browser.newPage(); // Open a new page
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

最後に、page.content() を使用して現在のページのすべての HTML コンテンツを取得する必要があります。最も重要なことは、システムの速度が低下する可能性がある不必要なメモリの使用を避けるために、ブラウザ インスタンスを閉じる必要があることです。スクリプトの最後でbrowser.close()を使用してブラウザを閉じます。

$ npm install cheerio puppeteer
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

現在のコードでは、ブラウザの読み込みと終了が非常に速くなり、ページをうまく表示できない可能性があります。この場合、page.waitForTimeout メソッドを使用してブラウザを数秒遅らせることができます。このメソッドは、browser.close メソッドの直前に指定する必要があります。

const puppeteer = require('puppeteer');
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

このセクションのコード全体は次のとおりです:

const url = 'https://www.scrapingcourse.com/button-click';
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

ファイルを保存し、以下のコマンドを使用してターミナル内でスクリプトを実行します。

(async () => {
    try {
        // Code goes here
    } catch (error) {
        console.error('Error:', error.message);
    }
})();
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

スクリプトにより、以下のようなヘッドレス ブラウザが開きます:

How to Scrape Data from a Page with Infinite Scroll

ブラウザがロードされ、Puppeteer が HTML コンテンツ全体を取得し、コンソールがコンテンツを端末に記録します。

ターミナルで得られる出力は次のとおりです:

// Launch Puppeteer
const browser = await puppeteer.launch({ headless: false }); // Headless mode
const page = await browser.newPage(); // Open a new page
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

次に、ループしてクリックをシミュレートします。シミュレーションでは、i 回実行する for ループが使用されます。ここで、i はクリック変数です。

// Navigate to the target URL
await page.goto(url, {
    waitUntil: 'networkidle2', // Ensure the page is fully loaded
});
ログイン後にコピー
ログイン後にコピー

: このセクションの残りのコードは、for ループの try ブロック内に記述する必要があります。

出力のデバッグと追跡を容易にするために、現在のクリック試行をログアウトします。

// Get the full HTML content of the page
const html = await page.content();

// Log the entire HTML content
console.log(html);

// Close the browser
await browser.close();
ログイン後にコピー
ログイン後にコピー

次に、「さらに読み込む」ボタンを見つけて、少なくとも 3 回クリックできるようにする必要があります。ただし、クリックをシミュレートする前に、[さらに読み込む] ボタンが利用可能であることを確認する必要があります。

Puppeteer は、要素を使用する前にその可視性をチェックする waitForSelector() メソッドを提供します。

「さらに読み込む」ボタンの場合は、まず ID セレクターの値を使用してボタンを見つけてから、次のように表示ステータスを確認する必要があります。

// Delay for 10 seconds to allow you to see the browser
await page.waitForTimeout(10000);
ログイン後にコピー
ログイン後にコピー

「さらに読み込む」ボタンが使用できることがわかったので、Puppeteer click() メソッドを使用してクリックできます。

const puppeteer = require('puppeteer');

const url = 'https://www.scrapingcourse.com/button-click';

(async () => {
    try {
        // Launch Puppeteer
        const browser = await puppeteer.launch({ headless: false }); // Headless mode
        const page = await browser.newPage(); // Open a new page

        // Navigate to the target URL
        await page.goto(url, {
            waitUntil: 'networkidle2', // Ensure the page is fully loaded
        });

        // Get the entire HTML content of the page
        const html = await page.content();

        // Log the entire HTML content
        console.log(html);

        // Delay for 10 seconds to allow you to see the browser
        await page.waitForTimeout(10000);

        // Close the browser
        await browser.close();
    } catch (error) {
        console.error('Error fetching the page:', error.message);
    }
})();
ログイン後にコピー
ログイン後にコピー

「さらに読み込む」ボタンのクリックをシミュレートしたら、データがサーバーのリクエストに依存する可能性があるため、コンテンツがロードされるまで待ってから別のクリックをシミュレートする必要があります。 setTimeout() を使用して、リクエスト間に遅延を導入する必要があります。

以下のコードは、「さらに読み込む」ボタンの別のクリックをシミュレートする前に、少なくとも 2 秒待つようにスクリプトに通知します。

$ node dynamicScraper.js
ログイン後にコピー
ログイン後にコピー

このセクションのまとめとして、クリックするたびに content() メソッドを使用して現在の HTML コンテンツを取得し、出力をターミナルにログアウトします。



    <title>Load More Button Challenge - ScrapingCourse.com</title>


    <header>
        <!-- Navigation Bar -->
        <nav>
            <a href="/">
                <img src="logo.svg" alt="無限スクロールでページからデータをスクレイピングする方法">
                <span>Scraping Course</span>
            </a>
        </nav>
    </header>

    <main>
        <!-- Product Grid -->
        <div>



<p>Note that the code structure above is what your output should look like.</p>

<p>Wow! You should be proud of yourself for getting this far. You’ve just completed your first attempt at scraping the contents of a webpage. </p>

<h2>
  
  
  Simulate the LOad More Products Process
</h2>

<p>Here, you want to access more products, and to do that, you need to click on the “Load more” button multiple times until you’ve either exhausted the list of all products or gotten the desired number of products you want to access. </p>

<p>To access this button and click on it, you must first locate the element using any CSS selectors (the class, id, attribute of the element, or tag name). </p>

<p>This tutorial aims to get at least 48 products from the target website, and to do that, you’ll have to click on the “Load more” button at least three times.</p>

<p>Start by locating the “Load more” button using any of the CSS selectors on it. Go to the target website, find the “Load more” button, right-click, and select the inspect option. </p>

<p><img src="https://img.php.cn/upload/article/000/000/000/173587927350910.jpg" alt="How to Scrape Data from a Page with Infinite Scroll"></p>

<p>Selecting the inspect option will open up developer tools just like the page below:</p>

<p><img src="https://img.php.cn/upload/article/000/000/000/173587927639663.jpg" alt="How to Scrape Data from a Page with Infinite Scroll"></p>

<p>The screenshot above shows that the “Load more” button element has an id attribute with the value "load-more-btn". You can use this id selector to locate the button during the simulation and click on it multiple times.</p>

<p>Back to the code, still inside the try block, after the line of code that logs out the previous HTML content for the default 12 products on the page.</p>

<p>Define the number of times you want to click the button. Recall that each click loads an additional 12 products. For 48 products, three clicks are required to load the remaining 36.<br>
</p>

<pre class="brush:php;toolbar:false">// Number of times to click "Load More"
const clicks = 3;
ログイン後にコピー

これまでの完全なコード:

for (let i = 0; i 



<p>ボタンを 3 回クリックして 48 個の製品を取得するシミュレーションの出力は次のとおりです:<br>
</p>

<pre class="brush:php;toolbar:false">console.log(`Clicking the 'Load More' button - Attempt ${i + 1}`);
ログイン後にコピー

ここでは、48 個の製品すべての出力のみを操作することだけを考慮する必要があります。これを行うには、最後のセクションの前のコードをクリーンアップする必要があります。

48 個の製品すべてで 1 つの出力だけが得られるように、for ループ ブロックの後に html 変数を取り出す必要もあります。

クリーンアップ コードは次のコード スニペットと同一である必要があります:

$ npm install cheerio puppeteer
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

それでは、Cheerio を使用した HTML 解析に入りましょう。

まず第一に、Cheerio は解析したい HTML コンテンツにアクセスする必要があります。そのために、その HTML コンテンツを取り込むload() メソッドを提供し、jQuery のような構文を使用してアクセスできるようにします。

HTML コンテンツを使用して Cheerio ライブラリのインスタンスを作成します。

const puppeteer = require('puppeteer');
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

$ を使用して、ロードされた HTML 内の要素をクエリおよび操作できるようになりました。

次に、製品情報を格納する配列を初期化します。この配列には抽出されたデータが保持され、各製品は名前、価格、画像、リンクを含むオブジェクトとして保存されます。

const url = 'https://www.scrapingcourse.com/button-click';
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

各製品には .product-item クラスがあることを思い出してください。これを Cheerio ($) の変数インスタンスとともに使用して各製品を取得し、いくつかの操作を実行します。

.each() メソッドは、.product-item クラス セレクターを使用して、一致した各要素を反復処理するために使用されます。

(async () => {
    try {
        // Code goes here
    } catch (error) {
        console.error('Error:', error.message);
    }
})();
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

特定の詳細のクラス セレクターを使用して、各製品から製品の詳細を取得しましょう。たとえば、製品名を取得するには、クラス セレクター .product-item を使用して各製品の子要素を検索する必要があります。その子要素のテキスト コンテンツを取得し、空白がある場合はトリミングします。

// Launch Puppeteer
const browser = await puppeteer.launch({ headless: false }); // Headless mode
const page = await browser.newPage(); // Open a new page
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
  • $(element).find('.product-name'): 現在の .product-item 内で、クラス .product-name.
  • を持つ子要素を検索します。
  • .text(): 要素内のテキスト コンテンツを取得します。
  • .trim(): テキストから不要な空白を削除します。

この概念を活用して、クラス属性を使用して価格、画像 URL、リンクを取得してみましょう。

// Navigate to the target URL
await page.goto(url, {
    waitUntil: 'networkidle2', // Ensure the page is fully loaded
});
ログイン後にコピー
ログイン後にコピー

期待される情報をすべて取得したので、次は、解析された各製品情報を個別のオブジェクトとして products 配列にプッシュします。

// Get the full HTML content of the page
const html = await page.content();

// Log the entire HTML content
console.log(html);

// Close the browser
await browser.close();
ログイン後にコピー
ログイン後にコピー

最後に、products 配列をログアウトして、ターミナルに期待される出力を取得します。

// Delay for 10 seconds to allow you to see the browser
await page.waitForTimeout(10000);
ログイン後にコピー
ログイン後にコピー

コード全体は次のコード スニペットのようになります。

const puppeteer = require('puppeteer');

const url = 'https://www.scrapingcourse.com/button-click';

(async () => {
    try {
        // Launch Puppeteer
        const browser = await puppeteer.launch({ headless: false }); // Headless mode
        const page = await browser.newPage(); // Open a new page

        // Navigate to the target URL
        await page.goto(url, {
            waitUntil: 'networkidle2', // Ensure the page is fully loaded
        });

        // Get the entire HTML content of the page
        const html = await page.content();

        // Log the entire HTML content
        console.log(html);

        // Delay for 10 seconds to allow you to see the browser
        await page.waitForTimeout(10000);

        // Close the browser
        await browser.close();
    } catch (error) {
        console.error('Error fetching the page:', error.message);
    }
})();
ログイン後にコピー
ログイン後にコピー

スクリプトを保存して実行すると、出力は次のようになります:

$ node dynamicScraper.js
ログイン後にコピー
ログイン後にコピー

製品情報をCSVにエクスポート

次のステップは、現在 JavaScript Object Notation (Json) 形式である解析済みの製品情報を、Comma-Separated Values (CSV) 形式にエクスポートすることです。 json2csv ライブラリを使用して、解析されたデータを対応する CSV 形式に変換します。

必要なモジュールをインポートすることから始めます。

Node.js は、ファイルへのデータの書き込みなどのファイル処理のためのファイル システム (fs) モジュールを提供します。 fs モジュールをインポートした後、json2csv ライブラリから parse() メソッドを構造化する必要があります。

$ npm install cheerio puppeteer
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

CSV ファイルには通常、列ヘッダーが必要です。これは、解析した情報と同じ順序で慎重に記述してください。ここで、解析されたデータは products 配列であり、各要素は 4 つのキー (名前、価格、画像、リンク) を持つオブジェクトです。適切にマッピングするには、これらのオブジェクト キーを使用して列ヘッダーに名前を付ける必要があります。

CSV ファイルのフィールド (列ヘッダー) を定義します。

const puppeteer = require('puppeteer');
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

フィールドを定義したので、次の操作は、現在解析された情報を CSV 形式に変換することです。 parse() メソッドは次の形式で動作します: parse(WHAT_YOU_WANT_TO_CONVERT, { YOUR_COLUMN_HEADERS }).

const url = 'https://www.scrapingcourse.com/button-click';
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

この CSV 情報を、.csv ファイル拡張子を付けて新しいファイルに保存する必要があります。 Node.js を使用する場合、fs モジュールの writeFileSync() メソッドを使用してファイルの作成を処理できます。このメソッドは、ファイル名とデータという 2 つのパラメーターを受け取ります。

(async () => {
    try {
        // Code goes here
    } catch (error) {
        console.error('Error:', error.message);
    }
})();
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

このセクションの完全なコードは次のようになります:

// Launch Puppeteer
const browser = await puppeteer.launch({ headless: false }); // Headless mode
const page = await browser.newPage(); // Open a new page
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

スクリプトを保存して実行すると、products.csv という名前のファイルがファイル構造に自動的に追加されることがわかります。

出力 - products.csv:
How to Scrape Data from a Page with Infinite Scroll

結論

このチュートリアルでは、非表示のコンテンツにアクセスするためにシミュレーションが必要なページからデータをスクレイピングする複雑な作業について詳しく説明しました。 Node.js といくつかの追加ライブラリを使用して動的ページで Web スクレイピングを実行し、スクレイピングされたデータをより整理された形式に解析し、CSV ファイルに解凍する方法を学習しました。

以上が無限スクロールでページからデータをスクレイピングする方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のおすすめ
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート