การยืนยันตัวตนพร็อกซีใน Selenium และ Playwright: ทุกวิธีที่ใช้งานได้ (2026)

เผยแพร่เมื่อ 4 มิถุนายน 2026 · อ่าน ≈10 นาที

นี่คือกับดักที่นักพัฒนา browser-automation ทุกคนต้องตกหลุมพรางสักครั้งหนึ่งพอดี: คุณเพิ่ม --proxy-server=http://user:pass@host:port เข้าไปใน launch flags ของ Chrome เบราว์เซอร์เริ่มทำงานได้ปกติ แล้วทุกหน้าก็ค้างอยู่ที่ป็อปอัปยืนยันตัวตนที่สคริปต์ของคุณมองไม่เห็นและคลิกไม่ได้ Chrome ตัดข้อมูลรับรอง (credentials) ออกจาก proxy flag อย่างเงียบ ๆ ไม่มี error ไม่มีบรรทัด log มีแค่กล่องโต้ตอบ modal ในเบราว์เซอร์ที่ไม่มีใครเฝ้าดู

คู่มือนี้คือแผนที่ฉบับสมบูรณ์ของวิธี การยืนยันตัวตน (authentication) ของพร็อกซีที่ใช้งานได้จริงใน Selenium และ Playwright ในปี 2026 — วิธีไหนควรใช้ วิธีไหนควรเลี่ยง และโค้ดที่แม่นยำสำหรับแต่ละวิธี (สำหรับการเลือกพร็อกซีและกลยุทธ์การหมุนเวียนในเครื่องมือเหล่านี้ ดูที่ การใช้พร็อกซีกับ Playwright & Puppeteer — บทความนี้พูดถึงเรื่องการส่งข้อมูลรับรองให้ผ่านล้วน ๆ)

ทำไม user:pass@host ถึงล้มเหลวในเบราว์เซอร์

ไคลเอนต์ HTTP แบบ command-line จะแยกข้อมูลรับรองออกจาก proxy URL และตอบ 407 Proxy Authentication Required ของพร็อกซีด้วยเฮดเดอร์ Proxy-Authorization ให้โดยอัตโนมัติ แต่ Chromium ไม่ทำแบบนั้น: --proxy-server รับเฉพาะ scheme://host:port เท่านั้น และเมื่อ 407 ตอบกลับมา มันจะแสดงกล่องโต้ตอบแบบโต้ตอบ ส่วนในโหมด headless ไม่มีแม้แต่กล่องโต้ตอบ — คำขอจะล้มเหลวไปเฉย ๆ

ดังนั้นคำถามจึงไม่เคยเป็น "ฉันจะใส่รหัสผ่านลงใน URL อย่างไร" — แต่เป็น "เลเยอร์ไหนจะตอบ 407 ให้ฉัน" มีคำตอบที่ใช้ได้สี่ข้อ เรียงจากดีที่สุดก่อน

วิธีที่ 1: Playwright Native Auth (ใช้วิธีนี้ถ้าทำได้)

Playwright แก้ปัญหานี้ได้อย่างถูกต้อง: มันตอบ challenge การยืนยันตัวตนของพร็อกซีเองผ่าน CDP ข้อมูลรับรองจะถูกใส่ไว้ใน launch หรือ context options:

# Python
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(
        proxy={
            "server": "http://us.jibaoproxy.com:913",
            "username": "USERNAME-session-job1",
            "password": "PASSWORD",
        }
    )
// Node.js - and per-context, which is where it gets powerful:
const browser = await chromium.launch({
  proxy: { server: 'per-context' }   // declare intent at launch
});
const ctx = await browser.newContext({
  proxy: {
    server: 'http://us.jibaoproxy.com:913',
    username: 'USERNAME-session-job2',
    password: 'PASSWORD',
  }
});

พร็อกซีแบบ per-context หมายความว่ากระบวนการเบราว์เซอร์เดียวสามารถรัน N contexts บน N sticky sessions ที่ต่างกันได้ — เป็นรากฐานของทุกการตั้งค่า scraping ด้วย Playwright ที่จริงจัง ถ้าคุณใช้ Playwright อยู่ ก็จบแล้ว ข้ามไปยังส่วนการตรวจสอบได้เลย ทุกอย่างด้านล่างนี้มีอยู่เพราะ Selenium ไม่มีสิ่งที่เทียบเท่ากัน

วิธีที่ 2: selenium-wire (Selenium, Python)

selenium-wire ห่อ Selenium ด้วยพร็อกซี MITM ในเครื่องที่จัดการการยืนยันตัวตนปลายทาง:

from seleniumwire import webdriver   # pip install selenium-wire

options = {
    "proxy": {
        "http":  "http://USERNAME:[email protected]:913",
        "https": "https://USERNAME:[email protected]:913",
    }
}
driver = webdriver.Chrome(seleniumwire_options=options)
driver.get("https://example.com")

ข้อควรระวังที่คุณควรรู้ก่อนนำไปใช้งานจริง:

วิธีที่ 3: Chrome Extension ที่แทรกข้อมูลรับรอง (Selenium, ทุกภาษา)

วิธีคลาสสิก: ส่วนขยายเล็ก ๆ ที่สร้างขึ้นเองซึ่งตั้งค่าพร็อกซีและตอบการยืนยันตัวตนผ่าน chrome.webRequest.onAuthRequired ไม่มี MITM ไม่มีกระบวนการเพิ่ม ใช้งานได้ใน Selenium ธรรมดา:

import zipfile, json

HOST, PORT = "us.jibaoproxy.com", 913
USER, PASS = "USERNAME-session-sel1", "PASSWORD"

manifest = {
    "version": "1.0.0", "manifest_version": 2, "name": "Proxy Auth",
    "permissions": ["proxy", "webRequest", "webRequestBlocking", ""],
    "background": {"scripts": ["background.js"]},
}
background = f"""
chrome.proxy.settings.set({{value: {{mode: "fixed_servers", rules: {{
  singleProxy: {{scheme: "http", host: "{HOST}", port: {PORT}}}
}}}}, scope: "regular"}}, () => {{}});
chrome.webRequest.onAuthRequired.addListener(
  () => ({{authCredentials: {{username: "{USER}", password: "{PASS}"}}}}),
  {{urls: [""]}}, ["blocking"]
);
"""

with zipfile.ZipFile("proxy_auth.zip", "w") as zp:
    zp.writestr("manifest.json", json.dumps(manifest))
    zp.writestr("background.js", background)

from selenium import webdriver
opts = webdriver.ChromeOptions()
opts.add_extension("proxy_auth.zip")
driver = webdriver.Chrome(options=opts)

มีจุดสะดุดสองอย่าง: ส่วนขยายจะไม่โหลดในโหมด headless แบบคลาสสิก — ใช้ --headless=new (Chrome 109+) หรือรันแบบ headed; และสคริปต์เบื้องหลังของ Manifest V2 ยังคงใช้งานได้สำหรับส่วนขยายอัตโนมัติที่ sideload เข้ามา แต่ให้จับตาดูไทม์ไลน์การเลิกใช้ MV2 ของ Chrome — ตัวเทียบเท่าแบบ MV3 ต้องใช้ service worker และ listener onAuthRequired เดียวกัน

วิธีที่ 4: Local Forwarder (ตัวสำรองสากล)

รันพร็อกซีในเครื่องเล็ก ๆ ที่เก็บข้อมูลรับรองไว้; แล้วชี้เบราว์เซอร์ไปที่ localhost โดยไม่ต้องยืนยันตัวตนเลย ใช้งานได้กับทุกเบราว์เซอร์ ทุกไดรเวอร์ ทุกภาษา ทั้ง headless และไม่ headless:

# Using pproxy (pip install pproxy) - terminal 1:
pproxy -l http://127.0.0.1:8899 \
       -r "http://USERNAME:[email protected]:913"

# Your script - terminal 2: plain Selenium, no auth needed
opts = webdriver.ChromeOptions()
opts.add_argument("--proxy-server=http://127.0.0.1:8899")
driver = webdriver.Chrome(options=opts)

นี่ยังเป็นคำตอบที่สะอาดที่สุดสำหรับ Firefox/geckodriver (ซึ่งทริคส่วนขยายใช้ไม่ได้) และสำหรับสภาพแวดล้อมแปลก ๆ อย่างการทดสอบแอป Electron ค่าใช้จ่าย: มีชิ้นส่วนที่ต้องดูแลเพิ่มอีกหนึ่งตัว และการกำหนดเส้นทางแบบ per-context ต้องใช้ forwarder หนึ่งพอร์ตต่อหนึ่ง session

การเปรียบเทียบวิธีการ

วิธีการใช้งานได้ในHeadlessSession แบบ per-contextคำตัดสินสำหรับการใช้งานจริง
Playwright nativePlaywrightได้ได้ตัวเลือกเริ่มต้น
selenium-wireSelenium (Py)ได้ต่อไดรเวอร์ใช้ได้ดีในระดับปานกลาง
Auth extensionSelenium (ทุกภาษา)--headless=new เท่านั้นต่อไดรเวอร์แน่น จับตาดู MV3
Local forwarderทุกอย่างได้หนึ่งพอร์ตต่อ sessionตัวสำรองสากล

ตรวจสอบว่ามันทำงานได้จริง

การ fallback กลับไปยัง IP จริงของคุณอย่างเงียบ ๆ คือโหมดความล้มเหลวที่ทำให้บัญชีถูกแบน ตรวจสอบ exit IP ที่จุดเริ่มต้นของทุกการรัน:

ip = driver.execute_script(
    "return fetch('https://api.ipify.org').then(r => r.text())"
) if hasattr(driver, 'execute_script') else page.evaluate(
    "fetch('https://api.ipify.org').then(r => r.text())"
)
assert ip != MY_REAL_IP, "Proxy not applied - aborting before we leak"
เครื่องมือฟรี · ไม่ต้องสมัคร

ตรวจสอบเบราว์เซอร์อัตโนมัติของคุณด้วยตา

สั่งเบราว์เซอร์ Selenium/Playwright ของคุณให้ไปที่หน้า What Is My IP ของเรา: มันจะแสดง exit IP, ตำแหน่งทางภูมิศาสตร์, ประเภท ASN และธง proxy/VPN ในมุมมองเดียว — ยืนยันได้ทันทีว่าเลเยอร์การยืนยันตัวตนทำงานและ IP เป็นแบบ residential

เปิดตัวตรวจสอบ IP →

เห็น ASN แบบ datacenter บนพร็อกซี "residential" หรือเปล่า? เปลี่ยนไปใช้พูลที่เป็น residential จริง ๆ — 500MB ทราฟฟิกฟรี →

คู่มืออ้างอิงการแก้ปัญหาแบบรวดเร็ว

สรุป

เบราว์เซอร์ไม่อ่าน proxy URL แบบ user:pass@ — ต้องมีบางอย่างคอยตอบ 407 ให้พวกมัน ใน Playwright สิ่งนั้นมีอยู่ในตัว; ใน Selenium มันคือ selenium-wire, ส่วนขยายยืนยันตัวตนที่สร้างขึ้น หรือ forwarder ในเครื่อง เลือกตาม stack ของคุณจากตารางเปรียบเทียบ แล้ว assert exit IP ในทุกการรัน เพื่อให้ความล้มเหลวของการยืนยันตัวตนแบบเงียบ ๆ ไม่มีวันรั่วที่อยู่จริงของคุณกลางการ crawl

ทดสอบทั้งสี่วิธีคืนนี้

500MB ทราฟฟิกฟรี — หนึ่งเกตเวย์ ทั้ง sticky หรือ rotating ทั้ง HTTP และ SOCKS5

เริ่มทดลองใช้ฟรี

สำหรับผลิตภัณฑ์ IP ทุกประเภท · พูลโหนดขนาดมหึมาพร้อมใช้งานได้ทุกเมื่อ

สมัครสมาชิกตอนนี้และรับเงินคืนการเติมเงินสูงสุด 100%

ผู้ใช้ใหม่รับ 500MB เมื่อสมัครสมาชิก พร้อมโบนัสในการเติมเงินครั้งแรก ข้อเสนอมีระยะเวลาจำกัด