[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"blog:post:vi:xay-dung-scraper-tin-dang-tin-yet":3},{"slug":4,"lang":5,"title":6,"summary":7,"date":8,"tags":9,"tag_slugs":15,"thumbnail_url":16,"translations":17,"body":18,"asset_base":19},"xay-dung-scraper-tin-dang-tin-yet","vi","Xây dựng Scraper Tin Đáng Tin Cậy: Xử Lý Giới Hạn Tốc Độ và CAPTCHA","Hướng dẫn chi tiết cách xây dựng scraper hiệu quả, xử lý giới hạn tốc độ và CAPTCHA, cùng ví dụ mã Python thực tế.","2026-06-24",[10,11,12,13,14],"scraper","proxy","python","captcha","rate-limiting",[10,11,12,13,14],"https://blog-api.ro-proxy.com/api/blog/posts/xay-dung-scraper-tin-dang-tin-yet/thumbnail.svg?lang=vi",[5],"## Giới thiệu\nTrong thế giới dữ liệu mở, scraper là công cụ không thể thiếu cho các nhà dữ liệu, marketer và nhà phát triển. Tuy nhiên, việc xây dựng một scraper tin cậy không chỉ là thu thập dữ liệu qua HTTP, mà còn phải đối phó với hai thách thức lớn: \n\n1. **Giới hạn tốc độ (rate limiting)** – Nhiều website áp dụng các chiến lược chặn IP hoặc giới hạn số lần truy cập trong một khoảng thời gian.\n2. **CAPTCHA** – Hệ thống bảo vệ chống bot, làm khó khăn cho việc tự động hóa.\n\nBài viết này sẽ cung cấp một khung thực tiếp để xây dựng scraper linh hoạt, bao gồm lựa chọn proxy, quản lý session, xử lý lỗi và phát hiện CAPTCHA, cùng các đoạn mã mẫu bằng Python.\n\n## 1. Xác định mục tiêu và kế hoạch\n- **Định dạng dữ liệu**: JSON, CSV hay database? \n- **Tần suất crawl**: một lần, hàng giờ, hàng ngày? \n- **Đối tượng mục tiêu**: trang sản phẩm, bài viết, dữ liệu người dùng? \n\nNhững quyết định này sẽ quyết định cách bạn cấu hình proxy, session và logic xử lý.\n\n## 2. Chọn loại proxy phù hợp\n| Kiểu proxy | Ưu điểm | Nhược điểm | Ứng dụng |\n|------------|---------|------------|----------|\n| Residential | Giảm khả năng bị chặn | Giá cao, tốc độ thay đổi | Scrape dữ liệu nhạy cảm, tránh IP block |\n| Datacenter | Mạnh mẽ, giá rẻ | Dễ bị phát hiện | Crawl dữ liệu công khai, test |\n| Mobile | Độ tin cậy cao | Hạn chế băng thông | Crawl dịch vụ mobile-first |\n\n- **Xử lý xoay vòng**: Sử dụng thư viện `ProxyPool` hoặc dịch vụ của RoProxy để tự động thay đổi IP.\n- **Sticky session**: Đối với trang cần login, giữ một IP ổn định cho mỗi session.\n\n## 3. Xây dựng session và quản lý yêu cầu\n```python\nimport requests\nfrom requests.adapters import HTTPAdapter\nfrom urllib3.util.retry import Retry\n\n# Thiết lập retry\nretry_strategy = Retry(\n    total=3,\n    backoff_factor=1,\n    status_forcelist=[429, 500, 502, 503, 504],\n    allowed_methods=frozenset(['GET', 'POST'])\n)\nadapter = HTTPAdapter(max_retries=retry_strategy)\n\n# Tạo session\nsession = requests.Session()\nsession.mount(\"https://\", adapter)\nsession.mount(\"http://\", adapter)\n\n# Thiết lập proxy\nproxy = {\n    'http': 'http://user:pass@proxy.example.com:8080',\n    'https': 'http://user:pass@proxy.example.com:8080'\n}\n```\n- `Retry` giúp tự động thử lại khi gặp lỗi 429 (Too Many Requests) hoặc lỗi server.\n- Giữ `session` tối ưu cho các request liên tiếp, giúp reuse TCP connections.\n\n## 4. Phát hiện và xử lý CAPTCHA\n### 4.1 Phát hiện\n- Kiểm tra mã trạng thái HTTP (thường 200 nhưng nội dung chứa biểu mẫu CAPTCHA).\n- Kiểm tra chuỗi HTML: `div` có id `captcha`, `img` chứa dữ liệu `src` chứa `captcha`.\n\n### 4.2 Giải quyết\n| Phương pháp | Khi nào dùng | Cách triển khai |\n|-------------|-------------|-----------------|\n| Tự động ngồi chờ | Trên mức giới hạn | `time.sleep()` + tăng độ trễ ngẫu nhiên |\n| Sử dụng captcha solver | Phải vượt qua | Dịch vụ 2captcha, anti-captcha |\n| Thay đổi User-Agent, header | Tránh phát hiện | Thêm `User-Agent`, `Accept-Language` |\n\n```python\nfrom time import sleep\nimport random\n\n# Giả sử response chứa CAPTCHA\nif 'captcha' in response.text.lower():\n    delay = random.randint(30, 60)  # Ngủ 30-60s\n    sleep(delay)\n    # Cập nhật headers\n    session.headers.update({'User-Agent': random_user_agent()})\n```\n\n## 5. Quản lý tốc độ và giới hạn\n### 5.1 Đặt giới hạn tốc độ\n- Sử dụng `asyncio` và `aiohttp` cho scraper đa luồng.\n- Đặt `asyncio.Semaphore` để giới hạn số lượng request đồng thời.\n\n```python\nimport asyncio\nimport aiohttp\n\nsemaphore = asyncio.Semaphore(5)  # 5 request đồng thời\n\nasync def fetch(url):\n    async with semaphore:\n        async with aiohttp.ClientSession() as session:\n            async with session.get(url) as resp:\n                return await resp.text()\n```\n\n### 5.2 Thêm delay ngẫu nhiên\n```python\nimport random\nimport time\n\nfor url in urls:\n    delay = random.uniform(1, 3)  # 1-3 giây\n    time.sleep(delay)\n    # Gửi request\n```\n\n## 6. Xử lý dữ liệu và lưu trữ\n- Dùng `BeautifulSoup` hoặc `lxml` để parse DOM.\n- Lưu dữ liệu vào CSV, SQLite hoặc MongoDB tùy nhu cầu.\n\n```python\nfrom bs4 import BeautifulSoup\nimport csv\n\nsoup = BeautifulSoup(html, 'html.parser')\nitems = soup.select('.product')\nwith open('data.csv', 'w', newline='') as f:\n    writer = csv.writer(f)\n    writer.writerow(['id', 'name', 'price'])\n    for item in items:\n        writer.writerow([item['data-id'], item.text.strip(), item.get('price')])\n```\n\n## 7. Kiểm tra, ghi log và cảnh báo\n- Ghi log với `logging` module.\n- Siêu cảnh báo khi gặp lỗi 429 nhiều lần hoặc CAPTCHA liên tục.\n- Sử dụng `Sentry` hoặc `Rollbar` để theo dõi lỗi.\n\n## 8. Thực hành: Scraper mẫu\n```python\nimport requests, time, random\nfrom bs4 import BeautifulSoup\n\nproxy_url = 'http://user:pass@proxy.example.com:8080'\nproxies = {'http': proxy_url, 'https': proxy_url}\nheaders = {'User-Agent': 'Mozilla/5.0'}\n\ndef get_page(url):\n    for _ in range(3):\n        resp = requests.get(url, headers=headers, proxies=proxies, timeout=10)\n        if resp.status_code == 200 and 'captcha' not in resp.text.lower():\n            return resp.text\n        elif resp.status_code == 429:\n            sleep_time = random.randint(30, 60)\n            time.sleep(sleep_time)\n    return None\n\nurls = ['https://example.com/page/{}'.format(i) for i in range(1, 101)]\nfor url in urls:\n    html = get_page(url)\n    if html:\n        soup = BeautifulSoup(html, 'html.parser')\n        # ... parse logic ...\n    time.sleep(random.uniform(1, 3))\n```\n\n## 9. Kết luận\n- **Proxy**: Lựa chọn đúng loại và xoay vòng IP là yếu tố quyết định.\n- **Retry + Delay**: Giúp vượt qua rate limiting mà không bị chặn mãn mã.\n- **Captcha handling**: Sự kết hợp giữa chờ, thay đổi header và dịch vụ giải mã.\n- **Ghi log**: Phụng thuyết giúp phát hiện nhanh lỗi.\n\nBằng cách áp dụng những phương pháp trên, bạn có thể xây dựng một scraper mạnh mẽ, ít bị chặn, và tuân thủ quy tắc của website. Đây là nền tảng vững chắc để phát triển các ứng dụng thu thập dữ liệu chuyên nghiệp.\n","https://blog-api.ro-proxy.com/api/blog/posts/xay-dung-scraper-tin-dang-tin-yet/assets"]