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
- Connection pooling –
httpx.AsyncClientđã hỗ trợ pool, giữ connection mở. - Batching – nếu cần scrape nhiều URL,lp thực hiện batch async.
- 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.
- 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.