Cập nhật lần cuối: 30 tháng 10, 2026.
Xác thực proxy Playwright: lỗi kết nối thường gặp và cách khắc phục
Khi Playwright không mở được trang qua proxy, thay đổi tùy ý các cài đặt thường khiến việc tìm nguyên nhân khó hơn. Trước hết hãy xác định phần nào thất bại: khởi động Chromium, kết nối tới proxy, xác thực proxy, kết nối HTTPS tới đích, hay chính trang đó.
Hướng dẫn này đi qua các bước kiểm tra theo thứ tự. Nó gồm URL proxy HTTP và SOCKS, sự khác biệt giữa xác thực proxy và đăng nhập website, các lỗi thường gặp như 407 và ERR_PROXY_CONNECTION_FAILED, cùng một script Python kiểm tra cổng ra proxy và đích HTTPS riêng biệt.
Bắt đầu bằng việc định vị lỗi
Hãy coi một yêu cầu trình duyệt như một chuỗi ngắn. Lỗi ở một bước không tự động nghĩa là bước tiếp theo cũng hỏng.

Tiến trình trình duyệt vẫn có thể khởi động khi proxy không tới được. Tương tự, kiểm tra IP có thể thành công trong khi đích khác hết thời gian chờ. Kiểm tra từng giai đoạn riêng trước khi cùng lúc đổi thông tin đăng nhập, giao thức và giá trị timeout.
Cài đặt proxy HTTP và SOCKS trong Playwright
Playwright nhận cài đặt proxy qua đối tượng proxy. Giá trị server xác định endpoint và giao thức proxy. Các trường username và password cung cấp thông tin đăng nhập cho xác thực proxy HTTP được hỗ trợ.
proxy = {
"server": "http://proxy.example.com:8080",
"username": "YOUR_USERNAME",
"password": "YOUR_PASSWORD",
}
browser = await playwright.chromium.launch(proxy=proxy)
Playwright cũng chấp nhận URL proxy SOCKS, ví dụ socks5://proxy.example.com:1080. Tài liệu mô tả username và password là thông tin đăng nhập tùy chọn cho proxy HTTP. Sự phân biệt này quan trọng: chấp nhận URL SOCKS không đảm bảo mọi tổ hợp trình duyệt và dịch vụ SOCKS đều hỗ trợ xác thực tên người dùng/mật khẩu. Đối chiếu endpoint và phương thức xác thực bạn dùng với Playwright Python network documentation
.
Trong bài kiểm thử Chromium của chúng tôi, endpoint SOCKS5 KindProxy có xác thực tên người dùng/mật khẩu trả về Browser does not support socks5 proxy authentication. Gateway proxy HTTP với tên người dùng/mật khẩu đã hoạt động trong bài kiểm đó. Đây là quan sát từ cấu hình kiểm thử đó, không phải khẳng định mọi phiên bản Playwright hay Chromium đều có cùng hạn chế. Trong hướng dẫn này, ví dụ chạy chính dùng xác thực proxy HTTP. Hãy kiểm thử SOCKS5 có xác thực riêng với đúng trình duyệt, endpoint và phương thức xác thực bạn định triển khai.
URL proxy và URL đích là khác nhau
Một proxy HTTP có thể mang yêu cầu tới website HTTPS. Ví dụ, http://proxy.example.com:8080 mô tả kết nối tới proxy; trang của bạn vẫn có thể là https://example.com. Trình duyệt thường yêu cầu proxy HTTP thiết lập đường hầm cho đích HTTPS, rồi đàm phán TLS với đích đó qua đường hầm.
URL proxy https:// nghĩa là kết nối từ trình duyệt tới chính proxy dùng TLS, nếu nhà cung cấp hỗ trợ endpoint đó. Nó không có nghĩa website đích là HTTPS; URL đích được cấu hình riêng. Dùng đúng scheme và cổng do nhà cung cấp proxy cấp.
Giữ xác thực proxy tách biệt với xác thực website
Ba cơ chế khác nhau dễ bị nhầm lẫn:
| Cơ chế | Ai kiểm tra? | Triệu chứng điển hình |
|---|---|---|
| Xác thực proxy HTTP | Máy chủ proxy | 407 Proxy Authentication Required |
| Danh sách IP được phép | Dịch vụ proxy kiểm tra IP client | Proxy từ chối máy có IP công cộng không nằm trong danh sách |
| Xác thực website | Website đích | Trang đăng nhập, 401, 403, hoặc thông báo riêng của ứng dụng |
Nếu trang hiện form đăng nhập của website, đổi mật khẩu proxy khó có thể sửa được. Nếu phản hồi là 407, hãy điều tra bước xác thực proxy trước. Website có thể trả 403 vì nhiều lý do; đừng giả định đó là lỗi thông tin đăng nhập proxy khi chưa kiểm tra nguồn phản hồi.
Với xác thực tên người dùng/mật khẩu, truyền giá trị dưới dạng trường riêng thay vì nhúng vào URL proxy. Giữ chúng trong biến môi trường hoặc tệp .env cục bộ được loại khỏi kiểm soát phiên bản. Nếu proxy dùng danh sách IP được phép, hãy làm theo thiết lập đó thay vì tự tạo cặp tên người dùng/mật khẩu.
Để xem quy trình kết nối lần đầu đầy đủ, xem hướng dẫn thiết lập proxy dân cư Playwright .
Sửa 407 Proxy Authentication Required
Phản hồi 407 nghĩa là proxy yêu cầu xác thực hoặc không chấp nhận thông tin đăng nhập đã nhận. Tùy cách trình duyệt và proxy xử lý xác thực thất bại, Chromium có thể lộ phản hồi 407 hoặc hiện lỗi điều hướng/mạng. Đừng dựa vào việc page.goto() luôn trả về đối tượng phản hồi khi xác thực proxy thất bại.
Kiểm tra các mục sau theo thứ tự:
- Xác nhận phương thức xác thực. Tài khoản dùng tên người dùng/mật khẩu hay danh sách IP được phép?
- Sao chép lại toàn bộ thông tin đăng nhập. Tên người dùng proxy có thể gồm trường nhắm mục tiêu hoặc phiên do nhà cung cấp tạo. Giữ nguyên giá trị đầy đủ.
- Kiểm tra endpoint và cổng. Thông tin đăng nhập có thể đúng nhưng được gửi tới gateway hoặc endpoint giao thức sai.
- Kiểm tra cách truyền các trường. Trong Playwright, dùng trường
usernamevàpasswordcủa đối tượngproxycho xác thực proxy HTTP. - Kiểm tra danh sách cho phép nếu đã bật. Đảm bảo máy chạy Playwright thoát qua IP mà tài khoản proxy cho phép.
- Kiểm thử từ cùng máy chủ. Kết nối thành công từ laptop không xác nhận thông tin đăng nhập hay danh sách cho phép từ máy chủ có IP công cộng khác.
Tránh thêm phương thức xác thực proxy thứ hai xung đột. Cũng tránh dán thông tin đăng nhập vào bản ghi terminal chia sẻ, kho mã nguồn hoặc ảnh chụp màn hình.
Sửa ERR_PROXY_CONNECTION_FAILED và hết thời gian chờ
ERR_PROXY_CONNECTION_FAILED thường chỉ ra việc trình duyệt không thể thiết lập kết nối tới proxy đã cấu hình. Nó khác với trang tải chậm sau khi kết nối proxy đã thành công.
| Triệu chứng | Kiểm tra trước |
|---|---|
| Chromium thoát trước khi mở trang | Cài đặt trình duyệt, thư viện hệ điều hành và tùy chọn khởi chạy |
ERR_PROXY_CONNECTION_FAILED | Hostname proxy, cổng, tiền tố giao thức, phân giải DNS và truy cập mạng đi |
Phản hồi 407 hoặc lỗi xác thực | Phương thức xác thực, tên người dùng/mật khẩu, hoặc danh sách cho phép |
| Kiểm tra IP thành công nhưng trang đích hết thời gian chờ | Khả năng tới đích, phản hồi riêng của đích và timeout điều hướng |
| Trang tải nhưng locator hết thời gian chờ | Trang mong đợi đã tải chưa và selector còn khớp không |
| Kết nối bị reset khi điều hướng HTTPS | Đường hầm proxy, kết nối đích và chi tiết lỗi TLS |
Đặt timeout điều hướng hợp lý, nhưng đừng coi timeout lớn hơn là cách sửa proxy không tới được. Nếu một endpoint thất bại, hãy kiểm tra IP và đích độc lập từ cùng máy. Đổi một biến mỗi lần để kết quả có ích.
Điều kiện chờ điều hướng của Playwright cũng quan trọng. domcontentloaded chờ nội dung DOM của tài liệu được phân tích; nó không nghĩa mọi hình ảnh, yêu cầu API hay thành phần render động đã xong. networkidle cũng không phải giải pháp phổ quát: trang có analytics, polling hoặc yêu cầu bền có thể không bao giờ idle. Hãy chờ phần tử trang hoặc trạng thái ứng dụng cụ thể mà tác vụ cần.
Chẩn đoán lỗi DNS, TLS và HTTPS
Lỗi DNS
Trước hết hãy phân biệt hostname proxy với hostname đích. Nếu máy không phân giải được gateway proxy, Playwright không thể kết nối tới endpoint đó. Phân giải tên đích có thể được xử lý khác tùy giao thức và triển khai proxy. So sánh yêu cầu qua proxy đã cấu hình với yêu cầu trực tiếp và ghi lại lỗi trình duyệt chính xác thay vì giả định mọi lỗi DNS xảy ra cục bộ.
Lỗi TLS và chứng chỉ
HTTPS gồm kết nối TLS tới đích. Nếu endpoint proxy tự dùng TLS, còn có kết nối TLS riêng giữa client và proxy. Lỗi ở một kết nối không xác định lỗi ở kết nối kia; hãy kiểm tra host đang lỗi và toàn bộ thông báo lỗi.
Đừng dùng ignore_https_errors=True như cách sửa chung. Nó tắt xác thực chứng chỉ và có thể che giấu vấn đề chứng chỉ, chặn bắt hoặc cấu hình. Chỉ dùng trong kiểm thử kiểm soát khi bạn hiểu vì sao xác thực chứng chỉ thất bại—không phải để làm biến mất lỗi production chưa giải thích.
Lỗi mạng Chromium thường gặp
ERR_NAME_NOT_RESOLVED: kiểm tra hostname nào không phân giải được và từ phía nào của kết nối proxy.ERR_TUNNEL_CONNECTION_FAILED: kiểm tra thiết lập đường hầm proxy, endpoint và phản hồi đích.ERR_CERT_AUTHORITY_INVALIDhoặc lỗi chứng chỉ khác: xác định chứng chỉ thuộc kết nối proxy hay site đích trước khi đổi cài đặt tin cậy.ERR_CONNECTION_RESET: so sánh cùng yêu cầu qua proxy và trực tiếp, rồi thử đích thứ hai.
Các tên lỗi này là manh mối chẩn đoán, không phải nguyên nhân gốc kết luận. Giữ đầu ra trình duyệt và so sánh với hướng dẫn kết nối của nhà cung cấp proxy.
Xác minh IP cổng ra proxy và kiểm tra HTTPS riêng
Một endpoint kiểm tra IP trả lời một câu hỏi: yêu cầu đó dùng IP công cộng nào? Nó không xác nhận website khác có tới được hay website sẽ trả nội dung bạn mong đợi.
Script dưới đây thực hiện hai yêu cầu riêng qua cùng ngữ cảnh trình duyệt:
- Endpoint kiểm tra IP, để xác minh IP cổng ra quan sát được.
- Một trang HTTPS riêng, để kiểm tra điều hướng đích và trạng thái phản hồi.
Nếu cái đầu thành công và cái thứ hai thất bại, hãy giữ sự phân biệt đó trong chẩn đoán. Cũng nhớ tra cứu địa lý IP chỉ là gần đúng; nó không chứng minh site sẽ hiện giá hoặc nội dung của một thị trường cụ thể.
Script chẩn đoán Python
Script dùng trình duyệt Chromium của Playwright và đọc cài đặt từ biến môi trường. Nó kiểm tra endpoint kiểm tra IP và URL đích trên các trang riêng, nên một lần điều hướng không ghi đè trạng thái trang kia.
Cài Playwright và python-dotenv, rồi cài Chromium:
python -m venv .venv
# macOS / Linux
source .venv/bin/activate
# Windows PowerShell
# .venv\Scripts\Activate.ps1
python -m pip install playwright python-dotenv
python -m playwright install chromium
Trên Linux, cài phụ thuộc hệ thống của Chromium nếu trình duyệt báo thiếu thư viện dùng chung:
python -m playwright install-deps chromium
Tạo tệp .env cạnh diagnose_proxy.py:
PROXY_SERVER=http://gw.kindproxy.com:12000
PROXY_USERNAME=your_dashboard_username
PROXY_PASSWORD=your_dashboard_password
CHECK_URL=https://api.ipify.org?format=json
TARGET_URL=https://example.com/
NAVIGATION_TIMEOUT_MS=30000
Thay placeholder bằng đúng endpoint và thông tin đăng nhập từ bảng điều khiển. Không bao giờ commit .env hoặc đưa thông tin đăng nhập thật vào nhật ký. Nếu dùng danh sách IP được phép, cấu hình theo hướng dẫn nhà cung cấp và để trống cả PROXY_USERNAME lẫn PROXY_PASSWORD.
Lưu đoạn sau thành diagnose_proxy.py:
import asyncio
import json
import os
from pathlib import Path
from dotenv import load_dotenv
from playwright.async_api import (
Error as PlaywrightError,
TimeoutError as PlaywrightTimeoutError,
async_playwright,
)
load_dotenv(Path(__file__).with_name(".env"))
def classify_error(error: Exception) -> str:
"""Return a useful hint without hiding the original Playwright error."""
message = str(error)
checks = (
("407", "Proxy authentication may have failed. Check credentials or IP allowlisting."),
("ERR_PROXY_CONNECTION_FAILED", "Chromium could not connect to the configured proxy endpoint."),
("ERR_TUNNEL_CONNECTION_FAILED", "The HTTPS tunnel through the proxy could not be established."),
("ERR_NAME_NOT_RESOLVED", "A hostname could not be resolved. Identify whether it is the proxy or destination hostname."),
("ERR_CERT", "TLS certificate validation failed. Identify whether the certificate belongs to the proxy or destination."),
("ERR_CONNECTION_RESET", "The connection was reset. Compare the proxy route and destination."),
)
for marker, explanation in checks:
if marker in message:
return explanation
return "No known error marker matched. Inspect the original Playwright error below."
async def check_url(
page,
label: str,
url: str,
timeout_ms: int,
expect_ip_json: bool = False,
) -> bool:
print(f"\n[{label}] {url}")
try:
response = await page.goto(
url,
wait_until="domcontentloaded",
timeout=timeout_ms,
)
if response is None:
print("No main-resource response was returned.")
return False
print(f"HTTP status: {response.status}")
print(f"Final URL: {page.url}")
if response.status == 407:
print(
"The response is HTTP 407. Check proxy authentication "
"or the account's IP allowlist."
)
return False
if not response.ok:
print(f"Request returned a non-success HTTP status: {response.status}")
return False
if expect_ip_json:
body = (await page.locator("body").inner_text()).strip()
try:
payload = json.loads(body)
except json.JSONDecodeError:
print(f"Expected JSON from the IP-check endpoint. Body: {body[:300]}")
return False
exit_ip = payload.get("ip") if isinstance(payload, dict) else None
if not exit_ip:
print("The IP-check response did not contain an 'ip' field.")
return False
print(f"Observed exit IP: {exit_ip}")
return True
except PlaywrightTimeoutError as error:
print("Navigation timed out. Check the destination and the timeout separately.")
print(f"Exception type: {type(error).__name__}")
print(f"Details: {error}")
return False
except PlaywrightError as error:
print(classify_error(error))
print(f"Exception type: {type(error).__name__}")
print(f"Details: {error}")
return False
async def main() -> int:
proxy_server = os.getenv("PROXY_SERVER", "").strip()
proxy_username = os.getenv("PROXY_USERNAME", "").strip()
proxy_password = os.getenv("PROXY_PASSWORD", "")
check_endpoint = os.getenv(
"CHECK_URL",
"https://api.ipify.org?format=json",
).strip()
target_url = os.getenv("TARGET_URL", "https://example.com/").strip()
try:
timeout_ms = int(os.getenv("NAVIGATION_TIMEOUT_MS", "30000"))
except ValueError as error:
raise ValueError("NAVIGATION_TIMEOUT_MS must be an integer.") from error
if not proxy_server:
raise ValueError("Set PROXY_SERVER to the proxy endpoint you want to test.")
if bool(proxy_username) != bool(proxy_password):
raise ValueError(
"Set both PROXY_USERNAME and PROXY_PASSWORD, or leave both empty "
"when using IP allowlisting."
)
if timeout_ms <= 0:
raise ValueError("NAVIGATION_TIMEOUT_MS must be greater than zero.")
proxy_settings = {"server": proxy_server}
if proxy_username and proxy_password:
proxy_settings["username"] = proxy_username
proxy_settings["password"] = proxy_password
async with async_playwright() as playwright:
try:
browser = await playwright.chromium.launch(proxy=proxy_settings)
except PlaywrightError as error:
print("Chromium could not launch with the configured proxy settings.")
print(classify_error(error))
print(f"Exception type: {type(error).__name__}")
print(f"Details: {error}")
return 1
try:
context = await browser.new_context()
ip_page = await context.new_page()
target_page = await context.new_page()
ip_ok = await check_url(
ip_page,
"PROXY IP CHECK",
check_endpoint,
timeout_ms,
expect_ip_json=True,
)
target_ok = await check_url(
target_page,
"HTTPS TARGET",
target_url,
timeout_ms,
)
finally:
await browser.close()
print("\nSummary:")
print(f"Proxy IP check: {'PASS' if ip_ok else 'FAIL'}")
print(f"HTTPS target check: {'PASS' if target_ok else 'FAIL'}")
return 0 if ip_ok and target_ok else 1
if __name__ == "__main__":
raise SystemExit(asyncio.run(main()))
Chạy từ cùng môi trường đã cài Playwright:
python diagnose_proxy.py
Script không bao giờ in tên người dùng hay mật khẩu proxy. Nó giữ nguyên kiểu và thông báo ngoại lệ để bạn thấy chẩn đoán gốc của trình duyệt thay vì “connection failed” chung chung. PASS cho kiểm tra IP và FAIL cho đích HTTPS nghĩa là hai đích hành xử khác nhau; tiếp tục khắc phục tuyến đích thay vì viết lại thông tin đăng nhập còn hợp lệ.
Định dạng đầu ra ví dụ
Các giá trị dưới đây chỉ minh họa định dạng; chúng không phải kết quả kiểm thử đã ghi lại:
[PROXY IP CHECK] https://api.ipify.org?format=json
HTTP status: 200
Observed exit IP: 203.0.113.10
[HTTPS TARGET] https://example.com/
HTTP status: 200
Final URL: https://example.com/
Summary:
Proxy IP check: PASS
HTTPS target check: PASS
203.0.113.10 là địa chỉ chỉ dùng trong tài liệu. Chỉ thay khối này bằng đầu ra thật sau khi chạy script, và xóa hoặc che IP cổng ra thật cùng thông tin đăng nhập trước khi công bố ảnh chụp.
Kiểm thử sticky session thực tế
Chúng tôi cũng chạy script chẩn đoán năm lần liên tiếp với cùng sticky session, tạm dừng ba giây giữa các lần chạy. Cả năm lần kiểm tra IP và yêu cầu đích HTTPS đều thành công với HTTP 200, và IP cổng ra quan sát được giữ nguyên 99.140.235.18 trong suốt bài kiểm ngắn này.

Điều này chỉ xác nhận tính nhất quán qua năm lần kiểm với khoảng cách ngắn. Nó không thiết lập ổn định phiên dài hạn hay đảm bảo truy cập các website khác. Hãy che IP cổng ra trong ảnh công khai nếu bạn không muốn tiết lộ.
Danh sách kiểm tra khắc phục nhanh
Trước khi đổi nhiều cài đặt, kiểm tra các mục sau theo thứ tự:
- Chromium có khởi động không có proxy không?
- Hostname proxy có phân giải được từ máy chạy Playwright không?
- Scheme, endpoint và cổng có đúng do nhà cung cấp cấp không?
- Tài khoản cấu hình tên người dùng/mật khẩu hay danh sách IP được phép?
- Yêu cầu kiểm tra IP có trả về IP qua trình duyệt không?
- Một đích HTTPS riêng có trả về phản hồi không?
- Lỗi là timeout điều hướng, trạng thái trang, hay chờ selector?
- Chứng chỉ đang được xác thực bình thường chứ? Đừng tắt xác minh để che lỗi chưa giải thích.
Nếu kiểm tra proxy và yêu cầu đích vẫn thất bại sau các bước này, lưu đúng kiểu ngoại lệ, thông báo, dấu thời gian, endpoint và đích. Chỉ chia sẻ nhật ký sau khi đã xóa thông tin đăng nhập và dữ liệu cá nhân.
FAQ
Lỗi 407 có do website gây ra không?
Thường thì 407 Proxy Authentication Required là phản hồi xác thực proxy. Phản hồi đăng nhập hoặc truy cập của website đích thường là trang đăng nhập, 401 hoặc 403. Xác nhận nguồn phản hồi trước khi đổi thông tin đăng nhập website. Cũng lưu ý xác thực proxy thất bại có thể hiện dưới dạng lỗi điều hướng trình duyệt thay vì đối tượng phản hồi.
Playwright có hỗ trợ SOCKS5 không?
Playwright chấp nhận URL proxy SOCKS. Khả năng tương thích xác thực phụ thuộc trình duyệt và endpoint. Các trường proxy tên người dùng/mật khẩu trong tài liệu dành cho xác thực proxy HTTP, và bài kiểm Chromium của chúng tôi không dùng được endpoint SOCKS5 KindProxy đã kiểm với xác thực tên người dùng/mật khẩu. Dùng cấu hình đã xác minh cho tài khoản và runtime của bạn.
Tại sao curl thành công còn Playwright thất bại?
Hai client có thể dùng cú pháp proxy, xử lý xác thực, hành vi DNS, cài đặt TLS hoặc timeout khác nhau. Chạy cả hai kiểm tra từ cùng máy, tới cùng đích, và so sánh thông báo lỗi chính xác.
Tôi có nên tăng timeout không?
Chỉ tăng khi kết nối đang tiến triển nhưng đích cần thêm thời gian. Timeout không sửa thông tin đăng nhập sai, cổng sai, lỗi DNS, hay proxy không tới được đích.
Điểm chính
Chẩn đoán lỗi proxy Playwright từng lớp một. Tách xác thực proxy khỏi đăng nhập website, xác minh IP cổng ra độc lập với site đích, và giữ nguyên chi tiết lỗi gốc.
Để thiết lập ban đầu, xem hướng dẫn tích hợp proxy Playwright . Nếu proxy dân cư phù hợp quy trình của bạn, so sánh gói proxy dân cư KindProxy và kiểm thử đúng endpoint cùng phương thức xác thực trước khi mở rộng.
