🎯 Trình duyệt đám mây tùy chỉnh, chống phát hiện được hỗ trợ bởi Chromium tự phát triển, thiết kế dành cho trình thu thập dữ liệu webtác nhân AI. 👉Dùng thử ngay
Quay lại blog

Những Cạm Bẫy Thường Gặp và Giải Pháp cho Trình Thu Thập Dữ Liệu Web (Kèm Ví Dụ Mã)

Michael Lee
Michael Lee

Expert Network Defense Engineer

16-Sep-2025

Công cụ thu thập dữ liệu không chỉ đơn thuần là gửi các yêu cầu HTTP—chúng phải xử lý việc kết xuất JavaScript, phòng chống bot, khả năng mở rộng và xử lý lỗi. Trong bài viết này, chúng ta sẽ khám phá những cạm bẫy phổ biến mà các nhà phát triển gặp phải khi xây dựng công cụ thu thập dữ liệu và cung cấp các giải pháp thực tiễn kèm theo đoạn mã mẫu.


1. Bỏ qua Robots.txt và Chính sách thu thập dữ liệu

Nếu công cụ thu thập dữ liệu của bạn bỏ qua robots.txt, bạn có nguy cơ gặp phải các vấn đề pháp lý hoặc bị chặn IP.

Thực hành không tốt:

python Copy
import requests

html = requests.get("https://example.com").text
# Không kiểm tra robots.txt

Cách tiếp cận tốt hơn:

python Copy
import urllib.robotparser

rp = urllib.robotparser.RobotFileParser()
rp.set_url("https://example.com/robots.txt")
rp.read()

if rp.can_fetch("*", "https://example.com/page"):
    print("Được phép thu thập dữ liệu")
else:
    print("Bị từ chối bởi robots.txt")

✅ Luôn tôn trọng chính sách thu thập dữ liệu và thực hiện giới hạn tốc độ.


2. Thu thập dữ liệu quá hung hãn

Gửi hàng nghìn yêu cầu mỗi giây là một cách nhanh chóng để bị cấm.

Giải pháp:

  • Thêm độ trễ
  • Sử dụng thu thập dữ liệu bất đồng bộ để nâng cao hiệu quả
python Copy
import asyncio, aiohttp, random

async def fetch(session, url):
    async with session.get(url) as resp:
        return await resp.text()

async def main():
    urls = ["https://example.com/page1", "https://example.com/page2"]
    async with aiohttp.ClientSession() as session:
        for url in urls:
            html = await fetch(session, url)
            print(len(html))
            await asyncio.sleep(random.uniform(1, 3))  # độ trễ lịch sự

asyncio.run(main())

3. Xử lý nội dung kết xuất bằng JavaScript

Công cụ thu thập dữ liệu tĩnh sẽ bỏ lỡ các trang nặng JavaScript (React, Vue, Angular).

Giải pháp: Sử dụng một trình duyệt không giao diện (ví dụ: Playwright, Puppeteer).

python Copy
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page()
    page.goto("https://quotes.toscrape.com/js/")
    print(page.content())  # giờ bao gồm nội dung đã được kết xuất bằng JS
    browser.close()

4. Khai thác dữ liệu không hiệu quả

Việc sử dụng các bộ chọn yếu dễ bị hỏng dẫn đến công cụ thu thập dữ liệu bị hỏng.

Cách tiếp cận tốt hơn với BeautifulSoup + phương án dự phòng:

python Copy
from bs4 import BeautifulSoup

html = "<div><h1 class='title'>Hello</h1></div>"
soup = BeautifulSoup(html, "lxml")

# Bộ chọn chính
title = soup.select_one("h1.title")

# Phương án dự phòng
if not title:
    title = soup.find("h1")

print(title.text)

5. Thu thập nội dung trùng lặp

Các URL như /page?id=123&session=abc có thể gây ra trùng lặp.

Giải pháp: Chuẩn hóa URL

python Copy
from urllib.parse import urlparse, urlunparse

def normalize(url):
    parsed = urlparse(url)
    clean = parsed._replace(query="")
    return urlunparse(clean)

print(normalize("https://example.com/page?id=1&session=xyz"))
# -> https://example.com/page

6. Chặn IP và Các cơ chế chống bot

Các trang web phát hiện bot bằng các bất thường về tốc độ, dấu vân tay, và CAPTCHA.

Luân phiên cơ bản với Scrapy:

python Copy
class RotateUserAgentMiddleware:
    user_agents = [
        "Mozilla/5.0 ...",
        "Chrome/91.0 ...",
        "Safari/537.36 ..."
    ]

    def process_request(self, request, spider):
        import random
        request.headers['User-Agent'] = random.choice(self.user_agents)

Giải pháp tổng hợp:

  • Luân phiên proxy và tác nhân người dùng
  • Sử dụng proxy dân cư/di động
  • Tích hợp trình giải CAPTCHA khi cần thiết

7. Xử lý lỗi

Các lỗi mạng là điều không thể tránh khỏi. Nếu không có lần thử lại, công cụ thu thập dữ liệu sẽ không thể hoạt động.

Ví dụ với các lần thử lại:

python Copy
import requests, time

def fetch(url, retries=3):
    for i in range(retries):
        try:
            return requests.get(url, timeout=5)
        except requests.exceptions.RequestException as e:
            print(f"Lỗi: {e}, đang thử lại {i+1}")
            time.sleep(2**i)
    return None

8. Thách thức về khả năng mở rộng

Một công cụ thu thập dữ liệu hoạt động cho 1.000 trang có thể gặp vấn đề khi lên tới 10 triệu trang.

Ví dụ thu thập dữ liệu phân tán với Scrapy + Redis:

bash Copy
scrapy runspider crawler.py -s JOBDIR=crawls/job1

Sử dụng:

  • Redis/Kafka cho hàng đợi tác vụ phân tán
  • Scrapy Cluster / Nutch để mở rộng
  • Lưu trữ đám mây cho các kết quả thu thập dữ liệu

9. Vấn đề chất lượng dữ liệu

Dữ liệu thu thập có thể chứa trùng lặp, trường trống, hoặc định dạng không hợp lệ.

Giải pháp: Xác thực cấu trúc

python Copy
from pydantic import BaseModel, ValidationError

class Product(BaseModel):
    name: str
    price: float

try:
    item = Product(name="Laptop", price="not a number")
except ValidationError as e:
    print(e)

10. An ninh và Tuân thủ

Các công cụ thu thập dữ liệu phải tránh thu thập PII hoặc dữ liệu bị hạn chế.
Luôn kiểm tra sự tuân thủ GDPR/CCPA trước khi lưu trữ dữ liệu người dùng.


Kết luận

Xây dựng một công cụ thu thập dữ liệu vững chắc cần độ chính xác kỹ thuật và trách nhiệm đạo đức. Bằng cách giải quyết các cạm bẫy như thu thập dữ liệu hung hãn, kết xuất JavaScript, phòng chống bot, và khả năng mở rộng, các nhà phát triển có thể thiết kế các công cụ thu thập dữ liệu tốt hơn.

  • Hiệu quả (sử dụng tài nguyên tối ưu)
  • Đàn hồi (chịu lỗi)
  • Tuân thủ (hợp pháp và đạo đức)

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