Quay lại blog

Cách cấu hình proxy trong Python requests cho việc phân tích, API và tự động hóa: hướng dẫn đầy đủ với ví dụ mã

Hướng dẫn đầy đủ về cách kết nối proxy trong thư viện Python requests - từ cài đặt cơ bản đến xoay vòng IP và vượt qua các khối khi phân tích và tự động hóa.

📅3 tháng 4, 2026
```html

Nếu script Python của bạn nhận được lỗi 403, CAPTCHA hoặc bị cấm theo IP — có nghĩa là trang web mục tiêu đã phát hiện ra bạn. Kết nối proxy với thư viện requests giải quyết vấn đề này: bạn thay đổi địa chỉ IP, vượt qua các hạn chế địa lý và phân phối tải giữa nhiều địa chỉ. Trong hướng dẫn này — mọi thứ từ kết nối cơ bản đến xoay vòng nâng cao với các ví dụ mã thực tế.

Tại sao cần proxy trong script Python

Hầu hết các trang web và API theo dõi địa chỉ IP của các yêu cầu đến. Nếu một địa chỉ thực hiện hơn 100 yêu cầu mỗi phút — nó sẽ bị chặn. Đây là biện pháp bảo vệ tiêu chuẩn chống lại bot, được sử dụng bởi Wildberries, Ozon, Avito, Google, Instagram và hàng trăm nền tảng khác. Proxy cho phép bạn chuyển yêu cầu qua một máy chủ trung gian với địa chỉ IP khác, làm cho bạn trở nên vô hình đối với các hệ thống bảo vệ.

Dưới đây là những nhiệm vụ chính mà proxy trong Python là cần thiết:

  • Phân tích các thị trường — thu thập giá từ Wildberries, Ozon, Yandex.Market mà không bị chặn theo IP
  • Theo dõi đối thủ — thực hiện các yêu cầu định kỳ đến các trang web của đối thủ mỗi 5–15 phút
  • Làm việc với API có giới hạn — phân phối các yêu cầu giữa nhiều IP để không vượt quá giới hạn tốc độ
  • Kiểm tra địa lý — kiểm tra cách trang web hiển thị từ các quốc gia và vùng khác nhau
  • Tự động hóa các biểu mẫu và đăng ký — tạo tài khoản hoặc điền biểu mẫu từ nhiều IP khác nhau
  • Theo dõi SEO — lấy vị trí từ các vùng khác nhau của Nga và các quốc gia khác

Không có proxy, ngay cả một parser được viết tốt cũng sẽ gặp phải việc bị chặn chỉ sau vài giờ làm việc. Với việc cấu hình xoay vòng IP đúng cách, cùng một script có thể hoạt động liên tục trong nhiều tuần mà không dừng lại.

Cấu hình cơ bản proxy trong requests

Thư viện requests hỗ trợ proxy một cách tự nhiên — không cần thêm gói nào khác. Proxy được truyền qua từ điển proxies trong các tham số yêu cầu.

Ví dụ đơn giản nhất — proxy HTTP cho một yêu cầu:

import requests

proxies = {
    "http": "http://123.45.67.89:8080",
    "https": "http://123.45.67.89:8080",
}

response = requests.get("https://httpbin.org/ip", proxies=proxies)
print(response.json())
# {'origin': '123.45.67.89'}
  

Lưu ý: trong từ điển proxies cần chỉ định cả hai khóa — httphttps. Nếu chỉ chỉ định một, các yêu cầu theo giao thức còn lại sẽ đi trực tiếp mà không qua proxy. Đây là một lỗi phổ biến của người mới, dẫn đến việc địa chỉ IP thực vẫn bị lộ.

Để đảm bảo rằng proxy hoạt động, hãy sử dụng dịch vụ httpbin.org/ip — nó trả về địa chỉ IP mà yêu cầu đến từ đó. Nếu trong phản hồi bạn thấy IP của máy chủ proxy, chứ không phải của bạn — mọi thứ đã được cấu hình đúng.

Proxy HTTP, HTTPS và SOCKS5: sự khác biệt và ví dụ mã

Proxy có nhiều loại khác nhau, và mỗi loại phù hợp với các nhiệm vụ riêng. Trong bối cảnh Python requests, điều quan trọng là hiểu sự khác biệt giữa ba giao thức chính:

Loại Giao thức trong URL Tốc độ Hỗ trợ UDP Kịch bản tốt nhất
HTTP http:// Cao Không Phân tích các trang web HTTP
HTTPS https:// Cao Không Phân tích các trang web bảo mật
SOCKS5 socks5:// Trung bình Độ ẩn danh hoàn toàn, bất kỳ giao thức nào

Để làm việc với SOCKS5 trong Python, bạn cần cài đặt gói bổ sung:

pip install requests[socks]
# hoặc riêng biệt:
pip install PySocks
  

Sau khi cài đặt, kết nối proxy SOCKS5 trông như sau:

import requests

# Proxy SOCKS5
proxies = {
    "http": "socks5://123.45.67.89:1080",
    "https": "socks5://123.45.67.89:1080",
}

response = requests.get("https://httpbin.org/ip", proxies=proxies)
print(response.json())
  

SOCKS5 là giao thức ưa thích cho các nhiệm vụ mà độ ẩn danh là quan trọng. Khác với proxy HTTP, SOCKS5 không thêm các tiêu đề X-Forwarded-For, có thể tiết lộ địa chỉ IP thực của bạn.

Proxy với xác thực bằng tên đăng nhập và mật khẩu

Hầu hết các dịch vụ proxy trả phí sử dụng xác thực bằng tên đăng nhập và mật khẩu. Đây là một thực tiễn tiêu chuẩn — nếu không có xác thực, proxy sẽ không cho phép yêu cầu của bạn. Trong thư viện requests, dữ liệu xác thực được truyền trực tiếp trong URL của proxy.

import requests

# Định dạng: giao thức://tên đăng nhập:mật khẩu@host:port
proxy_url = "http://myuser:[email protected]:8080"

proxies = {
    "http": proxy_url,
    "https": proxy_url,
}

response = requests.get("https://httpbin.org/ip", proxies=proxies)
print(response.status_code)
print(response.json())
  

Nếu trong mật khẩu hoặc tên đăng nhập có ký tự đặc biệt (ví dụ: @, #, %), chúng cần được mã hóa URL. Để làm điều này, hãy sử dụng mô-đun urllib.parse:

import requests
from urllib.parse import quote

username = "myuser"
password = "p@ss#word!"  # Ký tự đặc biệt

# Mã hóa URL tên đăng nhập và mật khẩu
encoded_user = quote(username, safe="")
encoded_pass = quote(password, safe="")

proxy_url = f"http://{encoded_user}:{encoded_pass}@123.45.67.89:8080"

proxies = {
    "http": proxy_url,
    "https": proxy_url,
}

response = requests.get("https://httpbin.org/ip", proxies=proxies)
print(response.json())
  

💡 Mẹo bảo mật

Không bao giờ mã hóa tên đăng nhập và mật khẩu trực tiếp trong mã của script. Sử dụng biến môi trường hoặc tệp .env với thư viện python-dotenv. Bằng cách này, bạn sẽ tránh được việc rò rỉ thông tin đăng nhập khi công bố mã trên GitHub.

Xoay vòng proxy: thay đổi IP tự động cho phân tích

Một proxy — vẫn chỉ là một địa chỉ IP, có thể bị chặn. Bảo vệ thực sự khỏi việc bị cấm — đó là xoay vòng: mỗi yêu cầu (hoặc mỗi N yêu cầu) sẽ đi từ một IP mới. Dưới đây là một vài phương pháp để thực hiện xoay vòng.

Phương pháp 1: Chọn ngẫu nhiên từ danh sách

import requests
import random

# Danh sách proxy
proxy_list = [
    "http://user:[email protected]:8080",
    "http://user:[email protected]:8080",
    "http://user:[email protected]:8080",
    "http://user:[email protected]:8080",
]

def get_random_proxy():
    proxy = random.choice(proxy_list)
    return {"http": proxy, "https": proxy}

# Phân tích 10 trang với xoay vòng IP
urls = [f"https://example.com/page/{i}" for i in range(1, 11)]

for url in urls:
    proxies = get_random_proxy()
    try:
        response = requests.get(url, proxies=proxies, timeout=10)
        print(f"URL: {url} | IP: {proxies['http'].split('@')[1]} | Trạng thái: {response.status_code}")
    except requests.RequestException as e:
        print(f"Lỗi: {e}")
  

Phương pháp 2: Xoay vòng tuần hoàn qua itertools

import requests
import itertools

proxy_list = [
    "http://user:[email protected]:8080",
    "http://user:[email protected]:8080",
    "http://user:[email protected]:8080",
]

# Tạo vòng lặp vô hạn qua danh sách proxy
proxy_cycle = itertools.cycle(proxy_list)

def get_next_proxy():
    proxy = next(proxy_cycle)
    return {"http": proxy, "https": proxy}

# Mỗi yêu cầu sử dụng proxy tiếp theo theo vòng
for i in range(9):
    proxies = get_next_proxy()
    response = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=10)
    print(f"Yêu cầu {i+1}: {response.json()['origin']}")
  

Đối với các nhiệm vụ công nghiệp với hàng nghìn yêu cầu mỗi giờ, nên sử dụng proxy cư trú với xoay vòng tự động tích hợp — nhà cung cấp tự động thay đổi IP cho mỗi yêu cầu qua một endpoint duy nhất, và bạn không cần quản lý danh sách địa chỉ thủ công.

Proxy qua Session: kết nối liên tục và cookie

Khi cần thực hiện nhiều yêu cầu trong một phiên (ví dụ: đăng nhập và sau đó thực hiện các yêu cầu), hãy sử dụng đối tượng requests.Session(). Nó lưu trữ cookie, tiêu đề và cài đặt proxy giữa các yêu cầu — không cần phải truyền proxy trong mỗi lần gọi riêng biệt.

import requests

# Tạo một phiên với proxy
session = requests.Session()
session.proxies = {
    "http": "http://user:[email protected]:8080",
    "https": "http://user:[email protected]:8080",
}

# Thêm tiêu đề để giả lập trình duyệt
session.headers.update({
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
    "Accept-Language": "ru-RU,ru;q=0.9",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
})

# Bước 1: Xác thực
login_data = {"username": "myuser", "password": "mypass"}
session.post("https://example.com/login", data=login_data)

# Bước 2: Các yêu cầu đã có cookie và qua proxy
response = session.get("https://example.com/dashboard")
print(response.status_code)

# Bước 3: Đóng phiên
session.close()
  

Sử dụng Session cũng hiệu quả hơn về mặt hiệu suất: kết nối TCP được tái sử dụng, thay vì mở lại cho mỗi yêu cầu. Khi phân tích hơn 1000 trang, điều này mang lại sự tăng tốc rõ rệt.

Xử lý lỗi, thời gian chờ và tự động lặp lại

Các máy chủ proxy có thể không khả dụng, phản hồi chậm hoặc trả về lỗi kết nối. Một script phân tích đáng tin cậy cần biết cách xử lý những tình huống này và tự động chuyển sang một proxy khác khi gặp sự cố.

import requests
import random
import time

proxy_list = [
    "http://user:[email protected]:8080",
    "http://user:[email protected]:8080",
    "http://user:[email protected]:8080",
]

def fetch_with_retry(url, max_retries=3, timeout=10):
    """
    Thực hiện yêu cầu với việc tự động chuyển đổi proxy khi có lỗi.
    Trả về đối tượng Response hoặc None khi hết lượt thử.
    """
    available_proxies = proxy_list.copy()
    random.shuffle(available_proxies)

    for attempt, proxy_url in enumerate(available_proxies[:max_retries], 1):
        proxies = {"http": proxy_url, "https": proxy_url}
        try:
            response = requests.get(
                url,
                proxies=proxies,
                timeout=timeout,
                headers={"User-Agent": "Mozilla/5.0"}
            )
            response.raise_for_status()  # Ném ngoại lệ khi 4xx/5xx
            print(f"✓ Thành công với lượt thử {attempt}")
            return response

        except requests.exceptions.ProxyError:
            print(f"✗ Lượt thử {attempt}: proxy không khả dụng — {proxy_url}")
        except requests.exceptions.Timeout:
            print(f"✗ Lượt thử {attempt}: thời gian chờ — {proxy_url}")
        except requests.exceptions.HTTPError as e:
            print(f"✗ Lượt thử {attempt}: Lỗi HTTP {e.response.status_code}")
            if e.response.status_code == 403:
                print("  → Nhận được lệnh cấm, thử proxy tiếp theo...")
        except requests.exceptions.RequestException as e:
            print(f"✗ Lượt thử {attempt}: lỗi chung — {e}")

        time.sleep(1)  # Tạm dừng giữa các lượt thử

    print(f"✗ Tất cả {max_retries} lượt thử đã hết cho {url}")
    return None

# Sử dụng
result = fetch_with_retry("https://httpbin.org/ip")
if result:
    print(result.json())
  

Lưu ý về raise_for_status() — phương pháp này tự động ném ngoại lệ khi có trạng thái HTTP 4xx và 5xx. Nếu không có nó, script sẽ coi phản hồi với mã 403 (bị cấm) hoặc 429 (vượt quá giới hạn yêu cầu) là thành công.

Proxy qua biến môi trường: lưu trữ dữ liệu an toàn

Thư viện requests tự động đọc các biến môi trường HTTP_PROXYHTTPS_PROXY. Điều này cho phép không lưu trữ thông tin đăng nhập trong mã và dễ dàng chuyển đổi giữa các proxy mà không cần thay đổi script.

Cài đặt biến trong terminal (Linux/macOS):

export HTTP_PROXY="http://user:[email protected]:8080"
export HTTPS_PROXY="http://user:[email protected]:8080"
export NO_PROXY="localhost,127.0.0.1"
  

Hoặc qua tệp .env với thư viện python-dotenv:

# Tệp .env (thêm vào .gitignore!)
HTTP_PROXY=http://user:[email protected]:8080
HTTPS_PROXY=http://user:[email protected]:8080
  
# Script Python
from dotenv import load_dotenv
import requests
import os

load_dotenv()  # Tải các biến từ .env

# requests tự động sử dụng HTTP_PROXY và HTTPS_PROXY
response = requests.get("https://httpbin.org/ip")
print(response.json())

# Hoặc rõ ràng từ các biến môi trường:
proxies = {
    "http": os.getenv("HTTP_PROXY"),
    "https": os.getenv("HTTPS_PROXY"),
}
response = requests.get("https://httpbin.org/ip", proxies=proxies)
print(response.json())
  

⚠️ Quan trọng: biến NO_PROXY

Biến NO_PROXY cho phép loại trừ một số địa chỉ khỏi việc sử dụng proxy. Nhất định thêm localhost127.0.0.1 để các yêu cầu cục bộ không đi qua proxy.

Các kịch bản thực tế: phân tích các thị trường, làm việc với API và tự động hóa

Hãy xem xét ba kịch bản thực tế mà các nhà phát triển thường gặp phải.

Kịch bản 1: Phân tích giá từ thị trường

Khi theo dõi giá trên Wildberries hoặc Ozon, điều quan trọng là phải giả lập hành vi của người dùng thực: truyền các tiêu đề trình duyệt đúng, thêm độ trễ giữa các yêu cầu và xoay vòng IP. Đối với nhiệm vụ này, proxy từ trung tâm dữ liệu là rất phù hợp — chúng nhanh và rẻ khi làm việc với khối lượng dữ liệu lớn.

import requests
import time
import random

HEADERS = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
                  "(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
    "Accept": "application/json, text/plain, */*",
    "Accept-Language": "ru-RU,ru;q=0.9",
    "Referer": "https://www.wildberries.ru/",
}

PROXIES = [
    {"http": "http://user:[email protected]:8080",
     "https": "http://user:[email protected]:8080"},
    {"http": "http://user:[email protected]:8080",
     "https": "http://user:[email protected]:8080"},
]

def get_product_price(article_id: int) -> dict:
    """Nhận giá sản phẩm theo mã từ Wildberries."""
    url = f"https://card.wb.ru/cards/v1/detail?appType=1&curr=rub&nm={article_id}"
    proxies = random.choice(PROXIES)

    try:
        resp = requests.get(url, headers=HEADERS, proxies=proxies, timeout=15)
        resp.raise_for_status()
        data = resp.json()
        product = data["data"]["products"][0]
        return {
            "id": product["id"],
            "name": product["name"],
            "price": product["salePriceU"] / 100,  # giá tính bằng kopecks
        }
    except (requests.RequestException, KeyError, IndexError) as e:
        return {"error": str(e)}

# Phân tích một số mã với độ trễ
articles = [12345678, 87654321, 11223344]
for article in articles:
    result = get_product_price(article)
    print(result)
    time.sleep(random.uniform(1.5, 3.0))  # Độ trễ ngẫu nhiên 1.5-3 giây
  

Kịch bản 2: Làm việc với API qua proxy

Một số API giới hạn số lượng yêu cầu từ một IP (giới hạn tốc độ). Phân phối các yêu cầu giữa nhiều proxy cho phép vượt qua giới hạn này:

import requests
import itertools
from typing import Optional

class ProxyAPIClient:
    """Khách hàng để làm việc với API qua xoay vòng proxy."""

    def __init__(self, api_key: str, proxy_list: list):
        self.api_key = api_key
        self.proxy_cycle = itertools.cycle(proxy_list)
        self.session = requests.Session()
        self.session.headers.update({
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json",
        })

    def _get_proxy(self) -> dict:
        proxy = next(self.proxy_cycle)
        return {"http": proxy, "https": proxy}

    def get(self, url: str, **kwargs) -> Optional[dict]:
        proxies = self._get_proxy()
        try:
            resp = self.session.get(url, proxies=proxies, timeout=10, **kwargs)
            resp.raise_for_status()
            return resp.json()
        except requests.RequestException as e:
            print(f"Yêu cầu API thất bại: {e}")
            return None

# Sử dụng
proxy_list = [
    "http://user:[email protected]:8080",
    "http://user:[email protected]:8080",
]

client = ProxyAPIClient(api_key="your_api_key", proxy_list=proxy_list)
data = client.get("https://api.example.com/products")
  

Kịch bản 3: Kiểm tra địa lý

Các nhà tiếp thị và chuyên gia SEO thường kiểm tra cách trang web hiển thị từ các vùng khác nhau. Với proxy từ các vị trí cần thiết, bạn có thể tự động hóa quá trình này:

import requests

# Proxy từ các vùng khác nhau
regional_proxies = {
    "Moscow":        "http://user:[email protected]:8080",
    "Saint Petersburg": "http://user:[email protected]:8080",
    "Novosibirsk":   "http://user:[email protected]:8080",
    "USA":           "http://user:[email protected]:8080",
}

url = "https://example.com/prices"

for region, proxy_url in regional_proxies.items():
    proxies = {"http": proxy_url, "https": proxy_url}
    try:
        resp = requests.get(url, proxies=proxies, timeout=15)
        print(f"[{region}] Trạng thái: {resp.status_code} | "
              f"Kích thước: {len(resp.content)} byte")
    except requests.RequestException as e:
        print(f"[{region}] Lỗi: {e}")
  

Loại proxy nào nên chọn cho nhiệm vụ của bạn

Việc chọn loại proxy ảnh hưởng trực tiếp đến thành công của dự án của bạn. Proxy từ trung tâm dữ liệu rẻ có thể hoạt động tốt cho một số nhiệm vụ và hoàn toàn thất bại cho những nhiệm vụ khác. Dưới đây là hướng dẫn thực tế để chọn:

Nhiệm vụ Loại proxy Tại sao
Phân tích các thị trường (Wildberries, Ozon) Proxy cư trú Trông giống như người dùng thông thường, ít bị cấm hơn
Phân tích dữ liệu công khai, tin tức Từ trung tâm dữ liệu Nhanh, rẻ, đủ ẩn danh
Làm việc với Facebook API, Instagram Proxy di động Mạng xã hội tin tưởng vào IP di động nhiều nhất
Kiểm tra địa lý Proxy cư trú với định vị địa lý Định vị chính xác, IP thực của vùng cần thiết
Phân tích có tải cao (10k+ yêu cầu/giờ) Từ trung tâm dữ liệu (pool) Tốc độ và chi phí khi có khối lượng lớn
Xác thực và làm việc với tài khoản Proxy cư trú hoặc di động Ít kích hoạt hệ thống chống gian lận hơn

Đối với các nhiệm vụ mà độ tin cậy tối đa và rủi ro tối thiểu khi làm việc với các trang web bảo mật là quan trọng, các nhà phát triển thường chọn proxy di động — chúng sử dụng địa chỉ IP từ các nhà cung cấp di động thực (MTS, Beeline, Megafon), rất hiếm khi bị đưa vào danh sách chặn.

Danh sách kiểm tra proxy trước khi sử dụng

  • ✅ Kiểm tra IP qua httpbin.org/ip — địa chỉ thực của bạn có hiển thị không?
  • ✅ Kiểm tra tốc độ — thời gian phản hồi không nên vượt quá 2-3 giây
  • ✅ Đảm bảo rằng proxy không nằm trong danh sách chặn qua blocklist.de hoặc ipqualityscore.com
  • ✅ Kiểm tra định vị địa lý qua ipinfo.io — có trùng với vùng mong đợi không?
  • ✅ Thử nghiệm trên trang mục tiêu với một yêu cầu trước khi chạy toàn bộ script
  • ✅ Đảm bảo rằng lưu lượng HTTPS cũng đi qua proxy (cả hai khóa trong từ điển)

Kết luận

Cấu hình proxy trong Python requests không khó, nhưng cần chú ý đến chi tiết. Các nguyên tắc chính cần nhớ: luôn chỉ định cả hai khóa (httphttps) trong từ điển proxy, sử dụng Session cho các kịch bản nhiều bước, luôn xử lý lỗi và thời gian chờ, và lưu trữ thông tin đăng nhập trong các biến môi trường, không phải trong mã.

Đối với việc phân tích công nghiệp với hàng nghìn yêu cầu mỗi ngày, danh sách proxy thủ công không đủ — cần có xoay vòng. Nếu bạn đang phân tích các thị trường bảo mật như Wildberries hoặc Ozon, làm việc với mạng xã hội hoặc kiểm tra định vị địa lý, chúng tôi khuyên bạn nên thử proxy cư trú — chúng cung cấp mức độ tin cậy cao từ các hệ thống chống bot và hỗ trợ xoay vòng IP tự động qua một endpoint duy nhất, điều này đơn giản hóa mã của script bạn rất nhiều.

```