Rumah >hujung hadapan web >tutorial js >Cara Mengikis Data daripada Halaman dengan Tatal Infinite

Cara Mengikis Data daripada Halaman dengan Tatal Infinite

Mary-Kate Olsen
Mary-Kate Olsenasal
2025-01-03 12:41:08782semak imbas

Pernahkah anda menemui halaman web yang memerlukan tindakan seperti "mengklik butang" untuk mendedahkan lebih banyak kandungan? Halaman sedemikian dipanggil "halaman web dinamik," kerana halaman tersebut memuatkan lebih banyak kandungan berdasarkan interaksi pengguna. Sebaliknya, halaman web statik memaparkan semua kandungannya serentak tanpa memerlukan tindakan pengguna.

Mengikis kandungan dari halaman dinamik boleh menjadi menakutkan kerana ia memerlukan simulasi interaksi pengguna, seperti mengklik butang untuk mengakses kandungan tersembunyi tambahan. Dalam tutorial ini, anda akan belajar cara mengikis data daripada halaman web dengan menatal tanpa had melalui butang "Muatkan lagi".

Prasyarat

Untuk mengikuti tutorial ini, anda memerlukan:

  • Node.js: Pasang versi yang ditandakan "LTS" (Sokongan Jangka Panjang), yang lebih stabil daripada versi terkini.
  • Npm: Ini ialah pengurus pakej yang digunakan untuk memasang pakej. Berita baiknya ialah "npm" dipasang secara automatik dengan Node.js, yang menjadikan perkara lebih pantas.
  • Cheerio: Untuk menghuraikan HTML
  • Puppeteer: Anda akan menggunakan ini untuk mengawal penyemak imbas tanpa kepala.
  • IDE untuk membina Scraper: Anda boleh mendapatkan mana-mana editor kod, seperti Visual Studio Code.

Selain itu, anda perlu mempunyai pemahaman asas tentang HTML, CSS dan JavaScript. Anda juga memerlukan penyemak imbas web seperti Chrome.

Mulakan Projek

Buat folder baharu, kemudian bukanya dalam editor kod anda. Cari tab "terminal" dalam editor kod anda dan buka terminal baharu. Begini cara anda boleh melihatnya menggunakan Kod Visual Studio.

How to Scrape Data from a Page with Infinite Scroll

Seterusnya, jalankan arahan berikut dalam terminal untuk memasang pakej yang diperlukan untuk binaan ini.

$ npm install cheerio puppeteer

Buat fail baharu di dalam folder projek anda dalam editor kod dan namakannya dynamicScraper.js.

Kerja cemerlang, kawan!

Mengakses Kandungan Halaman

Puppeteer ialah perpustakaan Node.js yang berkuasa yang membolehkan anda mengawal penyemak imbas Chrome tanpa kepala, menjadikannya ideal untuk berinteraksi dengan halaman web. Dengan Puppeteer, anda boleh menyasarkan halaman web menggunakan URL, mengakses kandungan dan mengekstrak data dengan mudah daripada halaman tersebut.

Dalam bahagian ini, anda akan belajar cara membuka halaman menggunakan penyemak imbas tanpa kepala, mengakses kandungan dan mendapatkan semula kandungan HTML halaman tersebut. Anda boleh mencari tapak web sasaran untuk tutorial ini di sini.

Nota: Anda perlu menulis semua kod di dalam dynamicScraper.js.

Mulakan dengan mengimport Puppeteer menggunakan fungsi terbina dalam require() Node.js, yang membantu anda memuatkan modul: modul teras, perpustakaan pihak ketiga (seperti Puppeteer) atau modul tersuai (seperti fail JS tempatan anda).

$ npm install cheerio puppeteer

Seterusnya, tentukan pembolehubah untuk menyimpan URL sasaran anda. Melakukan ini tidak wajib, tetapi ia menjadikan kod anda lebih bersih, kerana anda hanya perlu merujuk pembolehubah global ini dari mana-mana sahaja dalam kod anda.

const puppeteer = require('puppeteer');

Langkah seterusnya ialah mencipta fungsi yang akan melancarkan penyemak imbas tanpa kepala dan mendapatkan semula kandungan HTML halaman sasaran. Anda harus memilih kaedah Ungkapan Fungsi Segera (IIFE) untuk membuat perkara lebih cepat.

Tentukan IIFE tak segerak dengan blok cuba dan tangkap:

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

Nota: Anda harus menulis setiap kod lain untuk segmen tutorial ini di dalam blok percubaan.

Tepat di dalam IIFE, buat contoh baharu Puppeteer dan buka halaman baharu untuk interaksi.

Lancarkan contoh baharu pustaka dalang menggunakan kaedah pelancaran dan hantar mod tanpa kepala kepadanya. Mod tanpa kepala boleh ditetapkan sama ada kepada benar atau palsu. Menetapkan mod tanpa kepala kepada benar menjadikan penyemak imbas tanpa kepala tidak kelihatan apabila dalang dilancarkan, tetapi menetapkannya kepada palsu menjadikan penyemak imbas kelihatan.

Selepas anda melancarkan Puppeteer, anda juga mahu memanggil kaedah Halaman baharu, yang mencetuskan pembukaan tab baharu dalam penyemak imbas tanpa kepala.

(async () => {
    try {
        // Code goes here
    } catch (error) {
        console.error('Error:', error.message);
    }
})();

Sekarang, tanya kaedah Halaman baharu untuk menyasarkan URL yang dijangkakan dan buka tapak web tersebut dalam tab baharu ini menggunakan kaedah page.goto. Selain itu, anda ingin memastikan bahawa Puppeteer hanya menganggap halaman sedia untuk interaksi dan pengekstrakan data jika dan hanya jika halaman itu telah memuatkan semua sumber pentingnya (seperti imej dan JS).

Untuk memastikan halaman sedia, Puppeteer menyediakan pilihan yang dipanggil waitUntil, yang boleh mengambil pelbagai nilai yang mentakrifkan syarat yang berbeza untuk memuatkan halaman:

  • muat: Ini menunggu acara pemuatan dicetuskan, yang berlaku selepas dokumen HTML dan sumbernya (cth., imej, CSS, JS) dimuatkan. Walau bagaimanapun, ini mungkin tidak mengambil kira kandungan tambahan yang diberikan JavaScript yang dimuatkan selepas acara pemuatan.

  • domcontentloaded: Ini menunggu acara DOMContentLoaded, yang dicetuskan sebaik sahaja HTML awal dihuraikan. Tetapi ini dimuatkan sebelum sumber luaran (seperti imej atau JS tambahan) dimuatkan.

  • networkidle2: Ini menunggu sehingga tidak ada lebih daripada dua permintaan rangkaian aktif (permintaan HTTP yang berterusan (cth., memuatkan imej, skrip atau sumber lain)) selama 500 milisaat. Nilai ini diutamakan apabila berurusan dengan halaman yang membuat permintaan yang kecil dan berterusan tetapi tidak menjejaskan kandungan utama.

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

Akhir sekali, anda hanya perlu mendapatkan semula semua kandungan HTML halaman semasa menggunakan page.content(). Paling penting, anda harus menutup contoh penyemak imbas untuk mengelakkan penggunaan memori yang tidak perlu, yang boleh memperlahankan sistem anda. Gunakan browser.close() pada penghujung skrip anda untuk menutup penyemak imbas.

$ npm install cheerio puppeteer

Dengan kod yang anda miliki sekarang, penyemak imbas akan dimuatkan dan ditutup dengan pantas, malah anda mungkin tidak dapat melihat halaman tersebut dengan baik. Dalam kes ini, anda boleh menangguhkan penyemak imbas selama beberapa saat menggunakan kaedah page.waitForTimeout. Kaedah ini sepatutnya datang sebelum kaedah penyemak imbas.tutup.

const puppeteer = require('puppeteer');

Berikut ialah keseluruhan kod untuk bahagian ini:

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

Simpan fail anda dan jalankan skrip di dalam terminal anda menggunakan arahan di bawah:

(async () => {
    try {
        // Code goes here
    } catch (error) {
        console.error('Error:', error.message);
    }
})();

Skrip akan membuka pelayar tanpa kepala seperti di bawah:

How to Scrape Data from a Page with Infinite Scroll

Penyemak imbas dimuatkan, Puppeteer mengambil keseluruhan kandungan HTMLnya dan Console log kandungan ke terminal.

Berikut ialah output yang perlu anda perolehi dalam terminal anda:

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

Seterusnya, anda mahu gelung untuk mensimulasikan klik. Simulasi akan menggunakan gelung for yang dijalankan beberapa kali, di mana i akan menjadi pembolehubah klik.

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

Nota: Kod baki anda untuk bahagian ini hendaklah ditulis di dalam blok cuba dalam gelung for.

Untuk membantu menyahpepijat dan menjejaki output, log keluar percubaan klik semasa.

// 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();

Seterusnya, anda mahu dapat mencari butang "Muatkan lagi" dan klik padanya sekurang-kurangnya tiga kali. Tetapi sebelum mensimulasikan klik, anda harus memastikan butang "Muatkan lagi" tersedia.

Puppeteer menyediakan kaedah waitForSelector() untuk menyemak keterlihatan elemen sebelum menggunakannya.

Untuk butang "Muatkan lagi", anda perlu mencarinya terlebih dahulu menggunakan nilai pemilih id padanya dan kemudian menyemak status keterlihatan seperti ini:

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

Sekarang anda mengetahui butang “Muat lagi” tersedia, anda boleh mengkliknya menggunakan kaedah 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);
    }
})();

Setelah anda mensimulasikan klik pada butang "Muatkan lagi", anda harus menunggu kandungan dimuatkan sebelum mensimulasikan klik lain kerana data mungkin bergantung pada permintaan pelayan. Anda mesti memperkenalkan kelewatan antara permintaan menggunakan setTimeout().

Kod di bawah memberitahu skrip untuk menunggu sekurang-kurangnya dua saat sebelum mensimulasikan satu lagi klik pada butang “Muatkan lagi”.

$ node dynamicScraper.js

Untuk menyelesaikan perkara bagi bahagian ini, anda ingin mengambil kandungan HTML semasa selepas setiap klik menggunakan kaedah content() dan kemudian log keluar output ke terminal.



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


    <header>
        <!-- Navigation Bar -->
        <nav>
            <a href="/">
                <img src="logo.svg" alt="Cara Mengikis Data daripada Halaman dengan Tatal Infinite">
                <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;

Kod lengkap anda sehingga sekarang:

for (let i = 0; i 



<p>Berikut ialah output simulasi butang klik tiga kali untuk mendapatkan 48 produk:<br>
</p>

<pre class="brush:php;toolbar:false">console.log(`Clicking the 'Load More' button - Attempt ${i + 1}`);

Kini, anda hanya perlu mengambil berat tentang berinteraksi dengan hanya keluaran kesemua 48 produk. Untuk melakukan ini, anda perlu membersihkan kod sebelumnya di bahagian terakhir.

Anda juga perlu menurunkan pembolehubah html selepas blok gelung for supaya anda hanya mendapat satu output sahaja dengan kesemua 48 produk.

Kod pembersihan anda hendaklah sama dengan coretan kod ini:

$ npm install cheerio puppeteer

Sekarang, mari kita masuk ke penghuraian HTML menggunakan Cheerio.

Pertama sekali, Cheerio perlu mempunyai akses kepada kandungan HTML yang ingin dihuraikan, dan untuk itu, ia menyediakan kaedah load() yang mengambil kandungan HTML itu, menjadikannya boleh diakses menggunakan sintaks seperti jQuery.

Buat contoh pustaka Cheerio dengan kandungan HTML:

const puppeteer = require('puppeteer');

Anda kini boleh menggunakan $ untuk bertanya dan memanipulasi elemen dalam HTML yang dimuatkan.

Seterusnya, mulakan tatasusunan untuk menyimpan maklumat produk. Tatasusunan ini akan menyimpan data yang diekstrak dan setiap produk akan disimpan sebagai objek dengan nama, harga, imej dan pautannya.

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

Ingat bahawa setiap produk mempunyai kelas .produk-item. Anda akan menggunakan ini dengan contoh pembolehubah Cheerio ($) untuk mendapatkan setiap produk dan kemudian melakukan beberapa manipulasi.

Kaedah .each() digunakan untuk mengulangi setiap elemen yang dipadankan dengan pemilih kelas .product-item.

(async () => {
    try {
        // Code goes here
    } catch (error) {
        console.error('Error:', error.message);
    }
})();

Mari dapatkan butiran produk daripada setiap produk menggunakan pemilih kelas butiran tertentu itu. Contohnya, untuk mendapatkan nama produk, anda perlu mencari elemen anak dalam setiap produk dengan pemilih kelas .product-item. Dapatkan semula kandungan teks elemen kanak-kanak itu dan potong jika terdapat sebarang ruang putih.

// Launch Puppeteer
const browser = await puppeteer.launch({ headless: false }); // Headless mode
const page = await browser.newPage(); // Open a new page
  • $(elemen).find('.product-name'): Mencari dalam .product-item semasa untuk elemen anak dengan kelas .product-name.
  • .text(): Mengambil semula kandungan teks di dalam elemen.
  • .trim(): Mengalih keluar ruang putih yang tidak diperlukan daripada teks.

Memanfaatkan konsep ini, mari dapatkan harga, URL imej dan pautan menggunakan atribut kelas mereka.

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

Sekarang anda mempunyai semua maklumat yang dijangkakan, perkara seterusnya ialah menolak setiap maklumat produk yang dihuraikan sebagai objek individu kepada tatasusunan produk.

// 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();

Akhir sekali, log keluar tatasusunan produk untuk mendapatkan output yang dijangkakan dalam terminal.

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

Keseluruhan kod anda sepatutnya kelihatan seperti coretan kod ini:

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);
    }
})();

Berikut ialah rupa output anda apabila anda menyimpan dan menjalankan skrip:

$ node dynamicScraper.js

Eksport Maklumat Produk ke CSV

Langkah seterusnya ialah mengeksport maklumat produk yang dihuraikan, yang kini dalam format Notasi Objek JavaScript (Json), ke dalam format Nilai Dipisahkan Koma (CSV). Kami akan menggunakan pustaka json2csv untuk menukar data yang dihuraikan ke dalam format CSV yang sepadan.

Mulakan dengan mengimport modul yang diperlukan.

Node.js menyediakan modul sistem fail (fs) untuk pengendalian fail, seperti menulis data ke fail. Selepas mengimport modul fs, anda harus memusnahkan kaedah parse() daripada perpustakaan json2csv.

$ npm install cheerio puppeteer

Fail CSV biasanya memerlukan pengepala lajur; tulis ini dengan teliti dalam susunan yang sama seperti maklumat yang anda huraikan. Di sini, data yang dihuraikan ialah tatasusunan produk, di mana setiap elemen ialah objek dengan empat kekunci (nama, harga, imej dan pautan). Anda harus menggunakan kekunci objek ini untuk menamakan pengepala lajur anda untuk pemetaan yang betul.

Tentukan medan (Pengepala lajur) untuk fail CSV anda:

const puppeteer = require('puppeteer');

Sekarang anda telah menentukan medan anda, tindakan berikut adalah untuk menukar maklumat yang dihuraikan semasa kepada format CSV. Kaedah parse() berfungsi dalam format ini: parse(WHAT_YOU_WANT_TO_CONVERT, { YOUR_COLUMN_HEADERS }).

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

Anda kini perlu menyimpan maklumat CSV ini ke dalam fail baharu dengan sambungan fail .csv. Apabila menggunakan Node.js, anda boleh mengendalikan penciptaan fail menggunakan kaedah writeFileSync() pada modul fs. Kaedah ini mengambil dua parameter: nama fail dan data.

(async () => {
    try {
        // Code goes here
    } catch (error) {
        console.error('Error:', error.message);
    }
})();

Kod lengkap anda untuk bahagian ini sepatutnya kelihatan seperti ini:

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

Anda sepatutnya melihat penambahan automatik fail bernama products.csv pada struktur fail anda sebaik sahaja anda menyimpan dan menjalankan skrip.

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

Kesimpulan

Tutorial ini menyelidiki selok-belok mengikis data daripada halaman yang memerlukan simulasi untuk mengakses kandungan tersembunyinya. Anda mempelajari cara melakukan pengikisan web pada halaman dinamik menggunakan Node.js dan beberapa perpustakaan tambahan, menghuraikan data yang dikikis anda ke dalam format yang lebih teratur dan membongkarnya ke dalam fail CSV.

Atas ialah kandungan terperinci Cara Mengikis Data daripada Halaman dengan Tatal Infinite. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel sebelumnya:Bagaimanakah Saya Boleh Mengeluarkan Nilai Pendua dengan Cekap daripada Tatasusunan JavaScript?Artikel seterusnya:Bagaimanakah Saya Boleh Mengeluarkan Nilai Pendua dengan Cekap daripada Tatasusunan JavaScript?

Artikel berkaitan

Lihat lagi