🥳Tham gia Cộng đồng Scrapelessnhận thử nghiệm miễn phí của bạn để truy cập Bộ công cụ Web Scraping mạnh mẽ của chúng tôi!
Quay lại blog

Cách tối ưu hóa việc sử dụng lưu lượng truy cập trình duyệt của bạn nhiều nhất?

Alex Johnson
Alex Johnson

Senior Web Scraping Engineer

26-Apr-2025

Tổng quan

Khi sử dụng Puppeteer để thu thập dữ liệu, tiêu thụ lưu lượng là một yếu tố quan trọng cần xem xét. Đặc biệt khi sử dụng dịch vụ proxy, chi phí lưu lượng có thể tăng đáng kể. Để tối ưu hóa việc sử dụng lưu lượng, chúng ta có thể áp dụng các chiến lược sau:

  1. Chặn tài nguyên: Giảm tiêu thụ lưu lượng bằng cách chặn các yêu cầu tài nguyên không cần thiết.
  2. Chặn URL yêu cầu: Giảm thêm lưu lượng bằng cách chặn các yêu cầu cụ thể dựa trên đặc điểm URL.
  3. Mô phỏng thiết bị di động: Sử dụng cấu hình thiết bị di động để có được phiên bản trang nhẹ hơn.
  4. Tối ưu hóa toàn diện: Kết hợp các phương pháp trên để đạt được kết quả tốt nhất.

Kế hoạch tối ưu hóa 1: Chặn tài nguyên

Giới thiệu về Chặn tài nguyên

Trong Puppeteer, page.setRequestInterception(true) có thể bắt mọi yêu cầu mạng được khởi tạo bởi trình duyệt và quyết định tiếp tục (request.continue()), chấm dứt (request.abort()), hoặc tùy chỉnh phản hồi (request.respond()).

Phương pháp này có thể giảm đáng kể tiêu thụ băng thông, đặc biệt phù hợp cho các kịch bản thu thập dữ liệu, chụp màn hình, và tối ưu hóa hiệu suất.

Các loại tài nguyên có thể chặn và Đề xuất

Loại tài nguyên Mô tả Ví dụ Ảnh hưởng sau khi chặn Khuyến nghị
image Tài nguyên hình ảnh Hình ảnh JPG/PNG/GIF/WebP Hình ảnh sẽ không được hiển thị ⭐ An toàn
font Tệp phông chữ Phông chữ TTF/WOFF/WOFF2 Sẽ sử dụng phông chữ mặc định của hệ thống ⭐ An toàn
media Tệp phương tiện Tệp video/audio Nội dung phương tiện không thể phát được ⭐ An toàn
manifest Web App Manifest Tệp cấu hình PWA Chức năng PWA có thể bị ảnh hưởng ⭐ An toàn
prefetch Tài nguyên dự đoán <link rel="prefetch"> Ảnh hưởng tối thiểu đến trang ⭐ An toàn
stylesheet Tệp CSS Tệp CSS bên ngoài Kiểu trang bị mất, có thể ảnh hưởng đến bố cục ⚠️ Cẩn thận
websocket WebSocket Kết nối truyền thông thời gian thực Chức năng thời gian thực bị vô hiệu hóa ⚠️ Cẩn thận
eventsource Sự kiện gửi từ máy chủ Dữ liệu push từ máy chủ Chức năng push bị vô hiệu hóa ⚠️ Cẩn thận
preflight Yêu cầu tiền kiểm CORS Yêu cầu OPTIONS Yêu cầu giữa các nguồn gốc không thành công ⚠️ Cẩn thận
script Tệp JavaScript Tệp JS bên ngoài Chức năng động bị vô hiệu hóa, SPA có thể không hiển thị ❌ Tránh
xhr Yêu cầu XHR Yêu cầu dữ liệu AJAX Không thể lấy dữ liệu động ❌ Tránh
fetch Yêu cầu Fetch Yêu cầu AJAX hiện đại Không thể lấy dữ liệu động ❌ Tránh
document Tài liệu chính Chính trang HTML Trang không thể tải ❌ Tránh

Giải thích mức độ khuyến nghị:

  • An toàn: Việc chặn hầu như không ảnh hưởng đến việc thu thập dữ liệu hoặc hiển thị màn hình đầu tiên; được khuyến nghị chặn theo mặc định.
  • ⚠️ Cẩn thận: Có thể làm hỏng kiểu, chức năng thời gian thực, hoặc yêu cầu giữa các nguồn gốc; cần có sự phán đoán kinh doanh.
  • Tránh: Xác suất cao gây ra việc các trang SPA/tin động không hiển thị hoặc không thể lấy dữ liệu bình thường, trừ khi bạn hoàn toàn chắc chắn rằng bạn không cần các tài nguyên này.

Mã ví dụ về Chặn tài nguyên

javascript Copy
import puppeteer from 'puppeteer-core';

const scrapelessUrl = 'wss://browser.scrapeless.com/browser?token=your_api_key&session_ttl=180&proxy_country=ANY';

async function scrapeWithResourceBlocking(url) {
    const browser = await puppeteer.connect({
        browserWSEndpoint: scrapelessUrl,
        defaultViewport: null
    });
    const page = await browser.newPage();

    // Kích hoạt chặn yêu cầu
    await page.setRequestInterception(true);

    // Định nghĩa các loại tài nguyên cần chặn
    const BLOCKED_TYPES = new Set([
        'image',
        'font',
        'media',
        'stylesheet',
    ]);

    // Chặn các yêu cầu
    page.on('request', (request) => {
        if (BLOCKED_TYPES.has(request.resourceType())) {
            request.abort();
            console.log(`Đã chặn: ${request.resourceType()} - ${request.url().substring(0, 50)}...`);
        } else {
            request.continue();
        }
    });

    await page.goto(url, {waitUntil: 'domcontentloaded'});

    // Trích xuất dữ liệu
    const data = await page.evaluate(() => {
        return {
            title: document.title,
            content: document.body.innerText.substring(0, 1000)
        };
    });

    await browser.close();
    return data;
}

// Sử dụng
scrapeWithResourceBlocking('https://www.scrapeless.com')
javascript Copy
.then(data => console.log('Kết quả thu thập dữ liệu:', data))
    .catch(error => console.error('Thu thập dữ liệu không thành công:', error));

Kế hoạch Tối ưu hóa 2: Chặn URL Yêu cầu

Ngoài việc chặn theo loại tài nguyên, có thể thực hiện kiểm soát chặn tinh vi hơn dựa trên các đặc điểm của URL. Điều này đặc biệt hiệu quả trong việc chặn quảng cáo, các script phân tích và các yêu cầu bên thứ ba không cần thiết khác.

Chiến lược Chặn URL

  1. Chặn theo miền: Chặn tất cả các yêu cầu từ một miền cụ thể
  2. Chặn theo đường dẫn: Chặn các yêu cầu từ một đường dẫn cụ thể
  3. Chặn theo loại tệp: Chặn các tệp có phần mở rộng cụ thể
  4. Chặn theo từ khóa: Chặn các yêu cầu có URL chứa các từ khóa cụ thể

Mẫu URL Có thể Chặn Thường Gặp

Mẫu URL Mô tả Ví dụ Khuyến nghị
Dịch vụ quảng cáo Các miền mạng quảng cáo ad.doubleclick.net, googleadservices.com ⭐ An toàn
Dịch vụ phân tích Các script thống kê và phân tích google-analytics.com, hotjar.com ⭐ An toàn
Plugin mạng xã hội Nút chia sẻ xã hội, v.v. platform.twitter.com, connect.facebook.net ⭐ An toàn
Pixel theo dõi Pixel theo dõi hành vi người dùng Các URL chứa pixel, beacon, tracker ⭐ An toàn
Tệp truyền thông lớn Tệp video, âm thanh lớn Các phần mở rộng như .mp4, .webm, .mp3 ⭐ An toàn
Dịch vụ phông chữ Dịch vụ phông chữ trực tuyến fonts.googleapis.com, use.typekit.net ⭐ An toàn
Tài nguyên CDN Tài nguyên CDN tĩnh cdn.jsdelivr.net, unpkg.com ⚠️ Cẩn thận

Ví dụ Mã Chặn URL

javascript Copy
import puppeteer from 'puppeteer-core';

const scrapelessUrl = 'wss://browser.scrapeless.com/browser?token=your_api_key&session_ttl=180&proxy_country=ANY';

async function scrapeWithUrlBlocking(url) {
    const browser = await puppeteer.connect({
        browserWSEndpoint: scrapelessUrl,
        defaultViewport: null
    });
    const page = await browser.newPage();

    // Bật chặn yêu cầu
    await page.setRequestInterception(true);

    // Xác định các miền và mẫu URL cần chặn
    const BLOCKED_DOMAINS = [
        'google-analytics.com',
        'googletagmanager.com',
        'doubleclick.net',
        'facebook.net',
        'twitter.com',
        'linkedin.com',
        'adservice.google.com',
    ];

    const BLOCKED_PATHS = [
        '/ads/',
        '/analytics/',
        '/pixel/',
        '/tracking/',
        '/stats/',
    ];

    // Chặn các yêu cầu
    page.on('request', (request) => {
        const url = request.url();

        // Kiểm tra miền
        if (BLOCKED_DOMAINS.some(domain => url.includes(domain))) {
            request.abort();
            console.log(`Chặn miền: ${url.substring(0, 50)}...`);
            return;
        }

        // Kiểm tra đường dẫn
        if (BLOCKED_PATHS.some(path => url.includes(path))) {
            request.abort();
            console.log(`Chặn đường dẫn: ${url.substring(0, 50)}...`);
            return;
        }

        // Cho phép các yêu cầu khác
        request.continue();
    });

    await page.goto(url, {waitUntil: 'domcontentloaded'});

    // Trích xuất dữ liệu
    const data = await page.evaluate(() => {
        return {
            title: document.title,
            content: document.body.innerText.substring(0, 1000)
        };
    });

    await browser.close();
    return data;
}

// Sử dụng
scrapeWithUrlBlocking('https://www.scrapeless.com')
    .then(data => console.log('Kết quả thu thập dữ liệu:', data))
    .catch(error => console.error('Thu thập dữ liệu không thành công:', error));

Kế hoạch Tối ưu hóa 3: Giả lập Thiết bị Di động

Giả lập thiết bị di động là một chiến lược tối ưu hóa lưu lượng khác vì các trang web di động thường cung cấp nội dung trang nhẹ hơn.

Lợi ích của Giả lập Thiết bị Di động

  1. Phiên bản trang nhẹ hơn: Nhiều trang web cung cấp nội dung ngắn gọn hơn cho thiết bị di động
  2. Tài nguyên hình ảnh nhỏ hơn: Phiên bản di động thường tải hình ảnh nhỏ hơn
  3. CSS và JavaScript đơn giản hóa: Phiên bản di động thường sử dụng các kiểu và script đơn giản hơn
  4. Giảm quảng cáo và nội dung không cốt lõi: Phiên bản di động thường loại bỏ một số chức năng không cốt lõi
  5. Phản hồi thích ứng: Nhận bố cục nội dung tối ưu cho màn hình nhỏ

Cấu hình Giả lập Thiết bị Di động

Dưới đây là các tham số cấu hình cho một số thiết bị di động thường được sử dụng:

javascript Copy
const iPhoneX = {
    viewport: {
        width: 375,
        height: 812,
        deviceScaleFactor: 3,
        isMobile: true,
        hasTouch: true,
        isLandscape: false
    }
};

Hoặc sử dụng trực tiếp các phương pháp tích hợp sẵn của puppeteer để giả lập thiết bị di động

javascript Copy
import { KnownDevices } from 'puppeteer-core';
const iPhone = KnownDevices['iPhone 15 Pro'];
javascript Copy
const trình duyệt = await puppeteer.launch();
const trang = await trình duyệt.newPage();
await trang.emulate(iPhone);

Ví dụ Mô Phỏng Thiết Bị Di Động

javascript Copy
import puppeteer, {KnownDevices} from 'puppeteer-core';

const scrapelessUrl = 'wss://browser.scrapeless.com/browser?token=your_api_key&session_ttl=180&proxy_country=ANY';

async function scrapeWithMobileEmulation(url) {
    const trình duyệt = await puppeteer.connect({
        browserWSEndpoint: scrapelessUrl,
        defaultViewport: null
    });

    const trang = await trình duyệt.newPage();

    // Thiết lập mô phỏng thiết bị di động
    const iPhone = KnownDevices['iPhone 15 Pro'];
    await trang.emulate(iPhone);

    await trang.goto(url, {waitUntil: 'domcontentloaded'});
    // Trích xuất dữ liệu
    const dữ liệu = await trang.evaluate(() => {
        return {
            title: document.title,
            content: document.body.innerText.substring(0, 1000)
        };
    });

    await trình duyệt.close();
    return dữ liệu;
}

// Sử dụng
scrapeWithMobileEmulation('https://www.scrapeless.com')
    .then(dữ liệu => console.log('Kết quả thu thập:', dữ liệu))
    .catch(error => console.error('Thu thập thất bại:', error));

Ví dụ Tối Ưu Hóa Toàn Diện

Dưới đây là ví dụ toàn diện kết hợp tất cả các phương pháp tối ưu hóa:

javascript Copy
import puppeteer, {KnownDevices} from 'puppeteer-core';

const scrapelessUrl = 'wss://browser.scrapeless.com/browser?token=your_api_key&session_ttl=180&proxy_country=ANY';

async function optimizedScraping(url) {
    console.log(`Bắt đầu thu thập tối ưu: ${url}`);

    // Ghi lại mức sử dụng lưu lượng
    let tổngBytesĐãSửDụng = 0;

    const trình duyệt = await puppeteer.connect({
        browserWSEndpoint: scrapelessUrl,
        defaultViewport: null
    });

    const trang = await trình duyệt.newPage();

    // Thiết lập mô phỏng thiết bị di động
    const iPhone = KnownDevices['iPhone 15 Pro'];
    await trang.emulate(iPhone);

    // Thiết lập chặn yêu cầu
    await trang.setRequestInterception(true);

    // Xác định loại tài nguyên cần chặn
    const LOẠI_BỊ_CHẶN = [
        'image',
        'media',
        'font'
    ];

    // Xác định miền cần chặn
    const MIỀN_BỊ_CHẶN = [
        'google-analytics.com',
        'googletagmanager.com',
        'facebook.net',
        'doubleclick.net',
        'adservice.google.com'
    ];

    // Xác định đường dẫn URL cần chặn
    const ĐƯỜNG_DẪN_BỊ_CHẶN = [
        '/ads/',
        '/analytics/',
        '/tracking/'
    ];

    // Chặn các yêu cầu
    trang.on('request', (request) => {
        const url = request.url();
        const loạiTàiNguyên = request.resourceType();

        // Kiểm tra loại tài nguyên
        if (LOẠI_BỊ_CHẶN.includes(loạiTàiNguyên)) {
            console.log(`Chặn loại tài nguyên: ${loạiTàiNguyên} - ${url.substring(0, 50)}...`);
            request.abort();
            return;
        }

        // Kiểm tra miền
        if (MIỀN_BỊ_CHẶN.some(miền => url.includes(miền))) {
            console.log(`Chặn miền: ${url.substring(0, 50)}...`);
            request.abort();
            return;
        }

        // Kiểm tra đường dẫn
        if (ĐƯỜNG_DẪN_BỊ_CHẶN.some(đườngDẫn => url.includes(đườngDẫn))) {
            console.log(`Chặn đường dẫn: ${url.substring(0, 50)}...`);
            request.abort();
            return;
        }

        // Cho phép các yêu cầu khác
        request.continue();
    });

    // Giám sát lưu lượng mạng
    trang.on('response', async (response) => {
        const headers = response.headers();
        const độDàiNộiDung = headers['content-length'] ? parseInt(headers['content-length'], 10) : 0;
        tổngBytesĐãSửDụng += độDàiNộiDung;
    });

    await trang.goto(url, {waitUntil: 'domcontentloaded'});

    // Giả lập cuộn để kích hoạt nội dung tải lười
    await trang.evaluate(() => {
        window.scrollBy(0, window.innerHeight);
    });

    await new Promise(resolve => setTimeout(resolve, 1000))

    // Trích xuất dữ liệu
    const dữ liệu = await trang.evaluate(() => {
        return {
            title: document.title,
            content: document.body.innerText.substring(0, 1000),
            links: Array.from(document.querySelectorAll('a')).slice(0, 10).map(a => ({
                text: a.innerText,
                href: a.href
            }))
        };
    });

    // Xuất thống kê sử dụng lưu lượng
    console.log(`\nThống kê Sử dụng Lưu lượng:`);
    console.log(`Đã sử dụng: ${(tổngBytesĐãSửDụng / 1024 / 1024).toFixed(2)} MB`);

    await trình duyệt.close();
    return dữ liệu;
}

// Sử dụng
optimizedScraping('https://www.scrapeless.com')
    .then(dữ liệu => console.log('Hoàn thành thu thập:', dữ liệu))
    .catch(error => console.error('Thu thập thất bại:', error));

So Sánh Tối Ưu Hóa

Chúng ta thử xóa mã tối ưu hóa từ ví dụ toàn diện để so sánh lưu lượng trước và sau tối ưu hóa. Dưới đây là mã ví dụ không được tối ưu hóa:

javascript Copy
import puppeteer from 'puppeteer-core';
javascript Copy
const scrapelessUrl = 'wss://browser.scrapeless.com/browser?token=your_api_key&session_ttl=180&proxy_country=ANY';

async function optimizedScraping(url) {
  console.log(`Bắt đầu lấy dữ liệu tối ưu: ${url}`);

  // Ghi lại mức sử dụng lưu lượng
  let totalBytesUsed = 0;

  const browser = await puppeteer.connect({
    browserWSEndpoint: scrapelessUrl,
    defaultViewport: null
  });

  const page = await browser.newPage();

  // Đặt chặn yêu cầu
  await page.setRequestInterception(true);

  // Chặn các yêu cầu
  page.on('request', (request) => {
    request.continue();
  });

  // Giám sát lưu lượng mạng
  page.on('response', async (response) => {
    const headers = response.headers();
    const contentLength = headers['content-length'] ? parseInt(headers['content-length'], 10) : 0;
    totalBytesUsed += contentLength;
  });

  await page.goto(url, {waitUntil: 'domcontentloaded'});

  // Mô phỏng cuộn để kích hoạt nạp nội dung lười
  await page.evaluate(() => {
    window.scrollBy(0, window.innerHeight);
  });

  await new Promise(resolve => setTimeout(resolve, 1000))

  // Trích xuất dữ liệu
  const data = await page.evaluate(() => {
    return {
      title: document.title,
      content: document.body.innerText.substring(0, 1000),
      links: Array.from(document.querySelectorAll('a')).slice(0, 10).map(a => ({
        text: a.innerText,
        href: a.href
      }))
    };
  });

  // Xuất thông tin thống kê mức sử dụng lưu lượng
  console.log(`\nThống kê mức sử dụng lưu lượng:`);
  console.log(`Đã sử dụng: ${(totalBytesUsed / 1024 / 1024).toFixed(2)} MB`);

  await browser.close();
  return data;
}

// Sử dụng
optimizedScraping('https://www.scrapeless.com')
  .then(data => console.log('Lấy dữ liệu hoàn tất:', data))
  .catch(error => console.error('Lấy dữ liệu thất bại:', error));

Sau khi chạy mã không tối ưu, chúng ta có thể thấy sự khác biệt về lưu lượng một cách trực quan từ thông tin đã in ra:

Tình huống Lưu lượng đã sử dụng (MB) Tỉ lệ tiết kiệm
Không tối ưu 6.03
Tối ưu 0.81 ≈ 86.6 %

Bằng cách kết hợp các phương án tối ưu hóa ở trên, mức tiêu thụ lưu lượng proxy có thể được giảm đáng kể, hiệu quả lấy dữ liệu có thể được cải thiện, và đảm bảo rằng nội dung cốt lõi cần thiết được thu thập.

Tại Scrapless, chúng tôi chỉ truy cập dữ liệu có sẵn công khai trong khi tuân thủ nghiêm ngặt các luật, quy định và chính sách bảo mật trang web hiện hành. Nội dung trong blog này chỉ nhằm mục đích trình diễn và không liên quan đến bất kỳ hoạt động bất hợp pháp hoặc vi phạm nào. Chúng tôi không đảm bảo và từ chối mọi trách nhiệm đối với việc sử dụng thông tin từ blog này hoặc các liên kết của bên thứ ba. Trước khi tham gia vào bất kỳ hoạt động cạo nào, hãy tham khảo ý kiến ​​cố vấn pháp lý của bạn và xem xét các điều khoản dịch vụ của trang web mục tiêu hoặc có được các quyền cần thiết.

Bài viết phổ biến nhất

Danh mục