Quay lại danh sách
Triển khai hệ thống scraping đa nguồn với proxy rotating, FastAPI và Grafana

Triển khai hệ thống scraping đa nguồn với proxy rotating, FastAPI và Grafana

29 tháng 7, 2026

Giới thiệu

Trong thế giới dữ liệu ngày nay, việc thu thập thông tin từ nhiều nguồn website vẫn là một thách thức lớn. Đặc biệt là khi bạn muốn xây dựng một nền tảng scraping đa nguồn, bạn phải cân nhắc không chỉ về tốc độ lẫn độ tin cậy mà còn về mặt bảo mật và quản lý IP.

Đây là một bài hướng dẫn thực tế, hướng tới các developer muốn:

  • Tạo một API scraping dễ mở rộng bằng FastAPI.
  • Sử dụng proxy rotating để tránh bị chặn.
  • Giám sát các metric như latency, số request, error rate bằng Grafana.

Tất cả các thành phần sẽ dùng mã nguồn mở (Python, Docker, Prometheus, Grafana) và một proxy service chất lượng – bạn có thể thay thế bằng RoProxy khi muốn.

1. Kiến trúc tổng quan

+----------------+          +---------------- larga
|   Front‑end    |          |   Proxy Layer   |
|  (FastAPI)    |<-------->+-------------------
+----------------+   HTTP   |  proxy-rotator   |
                           +----------------
+----------------+    HTTP   +----------------
|   Scraper      |<-------->+  Target Website |
|   (Python)     |          +----------------
+----------------+                      |
                                     (Crawl)
  • FastAPI: là API gateway nhận request từ client (web/app), chuyển tiếp tới scraper.
  • Proxy‑rotator: module quản lý danh sách proxy regra, lựa chọn rando‑IP mới cho mỗi request.
  • Scraper: thực thi crawler, gửi HTTP requests thông qua proxy.
  • Grafana + Prometheus: thu thập metric từ FastAPI và scraper.

2. Chuẩn bị môi trường

2.1 Docker Compose

Chúng ta sẽ đóng gói từng component vào container riêng.

# docker-compose.yml
version: "3.8"
services:
  fastapi:
    build: ./fastapi
    depends_on:
      - prometheus
    environment:
      - PROXY_URL=http://proxy-rotator:8000/get
  scraper:
    build: ./scraper
    depends_on:
      - fastapi
    environment:
      - PROXY_URL=http://proxy-rotator:8000/get
  proxy-rotator:
    build: ./proxy_rotator
    environment:
      - PROXY_LIST=proxies.txt
  prometheus:
    image: prom/prometheus:latest
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
    command: --config.file=/etc/prometheus/prometheus.yml
  grafana:
    image: grafana/grafana:latest
    depends_on:
      - prometheus
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
    ports:
      - "3000:3000"

2.2 Tệp proxies.txt

http://user:pass@proxy1:3128
http://user:pass@proxy2:3128
http://user:pass@proxy3:3128

Bạn có thể lấy danh sách proxy miễn phí/đặt hàng từ RoProxy.

3. Xây dựng Proxy‑Rotator

Mục Giá: Cung cấp một endpoint /get trả về một proxy ngẫu nhiên.

# proxy_rotator/app.py
import os, random, json
from fastapi import FastAPI

(`/proxy-rotator`)
app = FastAPI()

proxy_file = os.getenv("PROXY_LIST", "proxies.txt")
with open(proxy_file) as f:
    proxies = [line.strip() for line in f if line.strip()]

@app.get("/get")
async def get_proxy():
    proxy = random.choice(proxies)
    return {"proxy": proxy}

Build:

FROM python:3.11-slim
WORKDIR /app
COPY app.py .
RUN pip install fastapi uvicorn
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]

4. FastAPI Gateway

FastAPI sẽ nhận request dạng GET /crawl?url=https://target.com.

# fastapi/main.py
import httpx, os
from fastapi import FastAPI, HTTPException
from pydantic import HttpUrl

app = FastAPI()
proxy_rotator_url = os.getenv("PROXY_URL", "http://proxy-rotator:8000/get")

@app.get("/crawl")
async def crawl(url: HttpUrl):
    # 1. Nhận proxy
    async with httpx.AsyncClient() as client:
        r = await client.get(proxy_rotator_url)
        r.raise_for_status()
        proxy = r.json()["proxy"]
    # 2. Gửi request tới target
    async with httpx.AsyncClient(proxies={"http": proxy, "https": proxy}, timeout=10) as client:
        try:
            resp = await client.get(str(url))
            resp.raise_for_status()
        except httpx.HTTPError as exc:
            raise HTTPException(status_code=502, detail=str(exc))
    # 3. Trả về nội dung
    return {"content": resp.text}

5. Scraper (Python)

Đây là một module có thể được gọi độc lập hoặc được FastAPI gọi để thực thi scraping sâu.

# scraper/worker.py
import httpx, asyncio, os, json
from bs4 import BeautifulSoup

proxy_rotator_url = os.getenv("PROXY_URL", "http://proxy-rotator:8000/get")

async def fetch(url):
    async with httpx.AsyncClient() as client:
        r = await client.get(proxy_rotator_url)
        r.raise_for_status()
        proxy = r.json()["proxy"]
    async with httpx.AsyncClient(proxies={"http": proxy, "https": proxy}, timeout=10) as client:
        r = await client.get(url)
        r.raise_for_status()
    return r.text

async def parse(html):
    soup = BeautifulSoup(html, "html.parser")
    titles = [t.text.strip() for t in soup.select("h1, .title")]
    return titles

async def main(url):
    html = await fetch(url)
    titles = await parse(html)
    print(titles)

if __name__ == "__main__":
    asyncio.run(main("https://example.com"))

6. Giám sát với Prometheus & Grafana

6.1 Prometheus Scrape config

# prometheus/prometheus.yml
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: "fastapi"
    static_configs:
      - targets: ["fastapi:8000"]
    metrics_path: "/metrics"
  - job_name: "scraper"
    static_configs:
      - targets: ["scraper:8000"]
    metrics_path: "/metrics"

FastAPI và Scraper cần expose /metrics endpoint (được FastAPI-Users hoặc Starlette metrics cung cấp).

6.2 Dashboard Grafana

Sau khi truy cập http://localhost:3000 (đăng nhập admin/admin), bạn có thể nhập Prometheus làm dữ liệu nguồn, tạo dashboard với các panels:

  • HTTP latency – biểu đồ line của latency request.
  • Error rate – tỷ lệ 5xx.
  • Active proxies – số proxy đang được sử dụng.

7. Tối ưu performance

  1. Connection poolinghttpx.AsyncClient đã hỗ trợ pool, giữ connection mở.
  2. Batching – nếu cần scrape nhiều URL,lp thực hiện batch async.
  3. Proxy rotation policy – thay vì chọn ngẫu nhiên, bạn có thể giới hạn số lần dùng một proxy, sau khi đạt giới hạn tự xoay.
  4. Retry logic – add httpx.Retry để tự động retry khi gặp lỗi 429.

8. Bảo mật và giới hạn

Mục tiêu Lệnh thực hiện
Tránh rò IP Cấu hình PROXY_URL trong container, không lưu proxy trong code
Vô hiệu DNS leak Sử dụng --proxy cho httpx, tránh DNS query qua đường mạng cổng ngoài
Giới hạn truy cập Sử dụng nginx hoặc traefik làm reverse proxy, limit rate

9. Kết luận

Bằng cách pha trộn FastAPI, proxy rotating, và hệ thống giám sát, bạn đãMDB một nền tảng scraping đa nguồn, có thể mở rộng và đáng tin cậy. Khi quy mô tăng lên, bạn chỉ cần thêm node mới vào Docker Compose hoặc chuyển sang Kubernetes.

Nếu bạn muốn một dịch vụ proxy chuyên nghiệp với IP đồng bộ, độ trễ thấp và SLA cao, hãy thử RoProxy – giải pháp proxy tối ưu cho mọi nhu cầu scraping.