Xoay danh sách proxy trong Python: tự xoay IP tĩnh bằng requests

Cập nhật:

Muốn xoay danh sách proxy trong Python, bạn chỉ cần ba thứ: một file chứa các proxy dạng ip:port:user:pass, một hàm chuyển mỗi dòng thành URL http://user:pass@ip:port, và một bộ chọn proxy cho từng request (xoay vòng, ngẫu nhiên hoặc gắn cố định theo phiên). Không cần dịch vụ proxy xoay riêng: với một nhóm IP tĩnh dùng riêng, bạn tự quyết định IP nào gửi request nào, bao lâu thì đổi và khi nào loại IP lỗi ra. Bài này đi từ cách đọc danh sách, ba kiểu xoay phổ biến, đến xử lý lỗi và chạy song song, kèm code mẫu dùng thư viện requests.

Tạo danh sách IP riêng để tự xoay

Tự xoay IP tĩnh khác gì dịch vụ proxy xoay

Dịch vụ proxy xoay cho bạn một cổng duy nhất, phía sau nhà cung cấp tự đổi IP theo từng request hoặc theo thời gian. Bạn không biết trước IP nào sẽ được dùng, cũng không chọn được IP nào giữ lại. Cách đó tiện cho việc cào số lượng rất lớn, nhưng khó kiểm soát khi cần biết chính xác request nào đi ra từ IP nào. Nếu muốn hiểu kỹ hai mô hình, đọc bài proxy tĩnh và proxy xoay khác nhau thế nào.

Khi tự xoay một danh sách IP tĩnh, mọi quyết định nằm trong code của bạn. Mỗi IP là của riêng bạn, không ai khác dùng chung, nên uy tín của IP phụ thuộc vào cách bạn gửi request. Bạn có thể ghi log từng request kèm IP, loại tạm một IP khi website trả lỗi, và giữ cố định IP cho một phiên đăng nhập. Đổi lại, bạn phải tự viết phần chọn proxy, retry và giới hạn tốc độ. Phần còn lại của bài là những đoạn code tối thiểu để làm việc đó cho đúng.

Bước 1: chuẩn bị danh sách proxy

Proxy được cấp ở định dạng ip:port:user:pass, mỗi dòng một proxy. Lưu toàn bộ vào file proxies.txt. Thư viện requests cần dạng URL, nên ta chuyển đổi một lần khi đọc file. Nếu mật khẩu có ký tự đặc biệt như @, : hay #, phải mã hoá URL, nếu không requests sẽ hiểu sai và bạn nhận lỗi 407 Proxy Authentication Required. Bạn cũng có thể đổi định dạng hàng loạt bằng công cụ chuyển định dạng proxy.

  • from urllib.parse import quote
  • def to_url(line):
  • ip, port, user, pw = line.strip().split(':', 3)
  • return 'http://' + quote(user, safe='') + ':' + quote(pw, safe='') + '@' + ip + ':' + port
  • PROXIES = [to_url(l) for l in open('proxies.txt') if l.strip()]
  • Dùng scheme http:// cho cả khoá http và https trong dict proxies. Với trang HTTPS, requests mở đường hầm CONNECT qua proxy HTTP, nên không cần proxy hỗ trợ TLS riêng.

Bước 2: ba cách xoay danh sách

Không có cách xoay nào đúng cho mọi trường hợp. Chọn theo việc bạn làm: cào trang công khai không đăng nhập thì xoay đều là đủ, còn việc có phiên đăng nhập hoặc giỏ hàng thì phải giữ một IP cho cả phiên.

  • Ví dụ xoay vòng: for url in urls: p = next(pool); r = requests.get(url, proxies={'http': p, 'https': p}, timeout=(5, 20))
  • Ví dụ sticky: đặt key là tên tài khoản hoặc domain, cùng một khoá luôn ra cùng một IP, kể cả khi bạn khởi động lại script. Dùng zlib.crc32 thay cho hash() vì hash() của Python đổi giá trị giữa các lần chạy.
Cách xoayCode cốt lõiKhi nào dùng
Xoay vòng trònpool = itertools.cycle(PROXIES) rồi next(pool)Cào trang công khai, muốn tải chia đều cho mọi IP
Ngẫu nhiênrandom.choice(PROXIES)Thứ tự request không quan trọng, muốn tránh nhịp lặp đều đặn
Gắn theo khoá (sticky)PROXIES[zlib.crc32(key.encode()) % len(PROXIES)]Một tài khoản, một phiên hoặc một domain luôn đi qua cùng một IP

Bước 3: dùng Session và gắn proxy theo phiên

Gọi requests.get() cho từng URL sẽ mở kết nối mới mỗi lần, tốn thời gian bắt tay TLS. Với một nhóm request cùng IP, hãy tạo một requests.Session() riêng cho mỗi proxy và tái sử dụng nó. Session giữ kết nối mở và giữ cookie, nên rất hợp với kiểu xoay sticky: mỗi phiên là một cặp IP và cookie cố định.

Một mẫu đơn giản là tạo dict sessions = {}, khi cần thì lấy s = sessions.setdefault(p, requests.Session()) rồi gán s.proxies = {'http': p, 'https': p}. Đừng dùng chung một Session rồi đổi proxy liên tục giữa các request, vì cookie của IP trước sẽ bị gửi kèm theo IP sau, website dễ thấy một phiên nhảy IP bất thường. Hướng dẫn cấu hình chi tiết hơn có trong trang cài proxy cho Python requests.

Bước 4: retry sang IP khác và tạm loại IP lỗi

Trong danh sách vài chục IP, sẽ có lúc một IP bị timeout hoặc website trả 403, 429 cho riêng IP đó. Code tốt không dừng cả script mà chuyển request sang IP khác, đồng thời cho IP vừa lỗi nghỉ một lúc. Cách làm gọn nhất là lưu thời điểm IP được dùng lại trong một dict cooldown = {}.

  • Bắt lỗi kết nối: except (requests.exceptions.ProxyError, requests.exceptions.ConnectTimeout, requests.exceptions.ReadTimeout) thì ghi nhận lỗi và thử IP tiếp theo.
  • Gặp mã 429 hoặc 403: đặt cooldown[p] = time.time() + 300 để IP nghỉ năm phút; khi chọn proxy, bỏ qua những IP có cooldown.get(p, 0) > time.time().
  • Giới hạn số lần thử, ví dụ tối đa ba IP cho một URL, để một trang hỏng không ăn hết cả danh sách.
  • Ghi log mỗi request gồm URL, IP, mã trạng thái và thời gian phản hồi. Khi có vấn đề, log này cho biết lỗi nằm ở một IP, ở cả nhóm hay ở website đích.
  • Nếu muốn đi xa hơn với theo dõi IP sống chết và phân bổ tải, đọc bài quản lý proxy pool.

Bước 5: chạy song song mà không dồn tải lên một IP

Khi dùng concurrent.futures.ThreadPoolExecutor, số luồng nên tỷ lệ với số IP chứ không phải đặt thật cao cho nhanh. Một quy tắc khởi đầu an toàn là số luồng không vượt quá số IP, và mỗi IP chỉ xử lý một request tại một thời điểm. Có thể làm việc này bằng queue.Queue chứa các proxy rảnh: luồng lấy một proxy ra, gửi request, chờ một khoảng ngắn rồi trả proxy về hàng đợi.

Thêm độ trễ ngẫu nhiên nhỏ giữa hai request trên cùng một IP, ví dụ time.sleep(random.uniform(1, 3)), giúp nhịp truy cập bớt máy móc và nhẹ cho máy chủ đích. Tốc độ phù hợp phụ thuộc vào từng website; bài giới hạn tốc độ khi cào dữ liệu giải thích cách ước lượng số request mỗi IP và số IP cần cho một khối lượng công việc.

Checklist trước khi chạy thật

  • Kiểm tra toàn bộ danh sách trước khi chạy bằng công cụ check proxy hoặc một request thử tới trang trả về IP, ví dụ requests.get('https://httpbin.org/ip', proxies=..., timeout=10).
  • Luôn đặt timeout, không bao giờ để mặc định, nếu không một IP treo có thể làm luồng đứng mãi.
  • Đặt User-Agent hợp lý và giữ nhất quán trong một phiên.
  • Tôn trọng robots.txt và điều khoản của website; chỉ thu thập dữ liệu công khai mà bạn được phép dùng.
  • Không lưu mật khẩu proxy trong mã nguồn đưa lên Git; đọc từ file hoặc biến môi trường.
  • Khi IP hết hạn thuê, gia hạn trên dashboard để giữ nguyên IP, tránh phải sửa lại danh sách và mất lịch sử log theo IP.

Câu hỏi thường gặp

Xoay danh sách proxy tĩnh có thay được proxy xoay dân cư không?

Với cào trang công khai ở tốc độ vừa phải thì thường là đủ, vì bạn chia tải cho nhiều IP riêng. Nếu website chặn mạnh mọi dải datacenter hoặc cần hàng nghìn IP khác nhau, tự xoay một danh sách nhỏ sẽ không thay được. VinaProxy hiện chưa bán proxy dân cư xoay.

Nên đổi IP sau mỗi request hay sau một khoảng thời gian?

Trang công khai không đăng nhập có thể đổi sau mỗi request. Việc có cookie, giỏ hàng hoặc đăng nhập thì giữ một IP cho cả phiên, vì đổi IP giữa phiên là tín hiệu bất thường.

Vì sao proxy chạy trong trình duyệt nhưng lỗi 407 trong Python?

Thường do mật khẩu có ký tự đặc biệt chưa được mã hoá URL, hoặc sai thứ tự user và pass khi tách chuỗi. Dùng quote(pw, safe='') như code mẫu trong bài.

Code này có dùng được với httpx hoặc aiohttp không?

Phần đọc danh sách và chọn proxy giữ nguyên. Chỉ khác cách truyền proxy: httpx nhận proxy khi tạo client, aiohttp nhận tham số proxy trong từng request.

Proxy có hỗ trợ SOCKS5 để dùng với requests không?

Proxy của VinaProxy dùng giao thức HTTP/HTTPS với xác thực user và mật khẩu. Bạn dùng scheme http:// như trong bài, không cần cài thêm gói SOCKS.

Tạo danh sách IP riêng để tự xoay

Proxy IPv4 riêng ở 7 nước, mỗi IP chỉ cấp cho một khách, cố định suốt thời gian thuê, không giới hạn băng thông, giao định dạng ip:port:user:pass.

Xem bảng giá

Bài viết liên quan

Cài đặt proxy
Cách cấu hình proxy HTTP(S) trong Python Requests chuẩn kỹ thuật
Hướng dẫn gắn proxy HTTP(S) có username và password vào thư viện Python requests, requests.Session(), xử lý lỗi ProxyError 407 và xoay vòng bể IP.
Kiến thức proxy
Quản lý proxy pool: từ danh sách IP đến hệ thống chạy ổn định
Cách quản lý proxy pool cho cào dữ liệu và tool: lưu danh mục IP, kiểm tra sống chết định kỳ, phân bổ theo việc, chính sách retry, ghi log và theo dõi hạn thuê.
Kiến thức proxy
Proxy tĩnh hay proxy xoay: chọn theo đúng công việc
So sánh proxy tĩnh và proxy xoay theo từng công việc: nuôi tài khoản, chạy ads, shop TMĐT, scraping, check SEO. Ưu nhược điểm, sticky session, cách tự xoay IP.
Proxy theo nền tảng
Proxy cho Web Scraping: cào dữ liệu tốc độ cao, không giới hạn băng thông
Mua proxy IPv4 riêng và ISP tĩnh tốc độ cao cho Python, Playwright, Selenium và Scrapy. Cào dữ liệu giá TMĐT, tin tức và API ổn định 24/7, băng thông thoải mái.
Sản phẩm
Proxy tĩnh (IP tĩnh dân cư ISP) Việt Nam & Mỹ
Mua proxy tĩnh ISP dân cư tại Mỹ và Việt Nam: IP đăng ký nhà mạng dân dụng, mỗi IP chỉ một khách dùng, băng thông không giới hạn. Xem giá và mua ngay.
Sản phẩm
Proxy IPv4 datacenter riêng
Mua, thuê proxy IPv4 datacenter riêng tại Mỹ, Việt Nam, Nhật Bản, Hàn Quốc, Singapore, Anh, Hồng Kông. HTTP(S), băng thông không giới hạn, kích hoạt tự động.
ISP · vietnam
Proxy ISP tĩnh Việt Nam: IP mạng gia đình cho các tài khoản giá trị nhất của bạn
Proxy dân cư tĩnh Việt Nam (ISP tĩnh): proxy IP tĩnh từ nhà mạng dân cư cho shop Shopee chính, TikTok Shop, tài khoản quảng cáo Facebook và Zalo OA.
IPV4 · united states
Proxy IPv4 riêng Mỹ: IP datacenter Hoa Kỳ nhanh, dùng riêng và ổn định
Thuê proxy IPv4 Mỹ dùng riêng cho cào dữ liệu, theo dõi thứ hạng, duyệt quảng cáo và nghiên cứu Amazon. IP tĩnh, 1 người 1 IP, băng thông không giới hạn.