為何在Selenium中代理認證較困難?
Chrome 接受 --proxy-server 運行參數來設置代理地址,但不接受地址中的用戶名和密碼。如果需要用戶名和密碼的代理連接,瀏覽器會彈出認證窗口,使用 Selenium 很難在此窗口中輸入值。
最乾淨的解決方案是IP授權。在儀表板中註冊運行Selenium的服務器或PC的IPv4地址,代理將接受該IP的連接,無需用戶名和密碼。這樣在Chrome中只需輸入ip:port即可。最多可註冊10個IP,便於多台服務器共同使用。
示例使用 IP 198.51.100.23,HTTP 端口 8000,SOCKS5 端口 1080。
pip install selenium如何在 Chrome 中連接 HTTP 代理?
註冊 IP 授權後,於 ChromeOptions 添加 --proxy-server 參數。Selenium 4.6+ 會自動透過 Selenium Manager 下載對應 chromedriver。
headless模式下參數設定相同。可透過IP檢查頁面確認當前顯示IP是否為代理IP。
from selenium import webdriver
from selenium.webdriver.common.by import By
opts = webdriver.ChromeOptions()
opts.add_argument("--proxy-server=http://198.51.100.23:8000") # this machine's IP is authorized in the dashboard
opts.add_argument("--headless=new")
driver = webdriver.Chrome(options=opts)
try:
driver.get("https://api.ipify.org")
print(driver.find_element(By.TAG_NAME, "body").text) # should print the proxy IP
finally:
driver.quit()如何在 Chrome 中使用 SOCKS5 代理?
在 --proxy-server 中填入 socks5:// 地址即可。Chrome 使用 SOCKS5 时,域名解析会在代理端进行,但在某些环境下,内部 DNS 解析可能仍然存在,因此常用 --host-resolver-rules 参数来阻止本地名称解析。
SOCKS5也支持IP認證連接。因為Chrome不支持SOCKS代理的用戶名和密碼認證。
from selenium import webdriver
opts = webdriver.ChromeOptions()
opts.add_argument("--proxy-server=socks5://198.51.100.23:1080")
# make sure host names are resolved through the proxy
opts.add_argument('--host-resolver-rules=MAP * ~NOTFOUND , EXCLUDE 198.51.100.23')
driver = webdriver.Chrome(options=opts)
driver.get("https://api.ipify.org")
print(driver.page_source)
driver.quit()如何連接 Firefox?
Firefox 通過環境變量設置代理。將 network.proxy.type 設置為 1(手動),並輸入 HTTP 或 SOCKS 地址和端口。對於 SOCKS5,將 network.proxy.socks_version 設置為 5,network.proxy.socks_remote_dns 設置為 True,這樣代理會負責名稱解析。
Firefox 也沒有通過運行設置輸入代理密碼的方法,因此使用 IP 授權是最簡單的。
from selenium import webdriver
opts = webdriver.FirefoxOptions()
opts.set_preference("network.proxy.type", 1)
opts.set_preference("network.proxy.socks", "198.51.100.23")
opts.set_preference("network.proxy.socks_port", 1080)
opts.set_preference("network.proxy.socks_version", 5)
opts.set_preference("network.proxy.socks_remote_dns", True)
driver = webdriver.Firefox(options=opts)
driver.get("https://api.ipify.org")
print(driver.page_source)
driver.quit()如何用不同IP同時啟動多個瀏覽器?
為每個瀏覽器設置不同代理地址分別運行即可。以下代碼示例通過API獲取ip:port列表並用3個不同IP啟動瀏覽器。注意單個瀏覽器內存佔用較高,請根據服務器規格設定並發數量。
像登入會話這樣長時間使用瀏覽器的任務,最好將一個IP固定到一個瀏覽器,直到任務完成才更換。
import requests
from selenium import webdriver
KEY = "YOUR_API_KEY"
lines = requests.get(
"https://socks5proxy.io/api/v1/proxies/download",
params={"format": "ip:port", "protocol": "http"},
headers={"Authorization": "Bearer " + KEY},
timeout=30,
).text.split()
drivers = []
for line in lines[:3]:
opts = webdriver.ChromeOptions()
opts.add_argument("--headless=new")
opts.add_argument("--proxy-server=http://" + line)
drivers.append(webdriver.Chrome(options=opts))
for d in drivers:
d.get("https://api.ipify.org")
print(d.page_source)
d.quit()如果必須使用用戶名·密碼驗證怎麼辦?
若環境不支援 IP 授權(如出口 IP 變動),可透過 selenium-wire 等庫代填認證,或於本地架設無驗證中繼代理轉發請求。
兩種方法都會增加一個組件,管理起來更複雜。如可能,在固定IP伺服器使用IP認證最簡單快速。
如何設置瀏覽器環境以匹配目標國家?
根據 IP 國家調整 Chrome 的 --lang 參數及 Accept-Language 設定,頁面將以該國語言顯示。若時區關鍵,可使用 CDP 指令 Emulation.setTimezoneOverride 同步時區。
使用 --window-size 參數設置窗口大小,如果需要手機屏幕,可以使用移動設備模擬設置。將這些值設置為國家配置包,可以在多個國家一致地運行相同的測試。
from selenium import webdriver
opts = webdriver.ChromeOptions()
opts.add_argument("--proxy-server=http://198.51.100.23:8000")
opts.add_argument("--lang=de-DE")
opts.add_argument("--window-size=1366,900")
driver = webdriver.Chrome(options=opts)
driver.execute_cdp_cmd("Emulation.setTimezoneOverride", {"timezoneId": "Europe/Berlin"})
driver.get("https://example.com/")
driver.quit()Selenium Grid或遠程瀏覽器也用相同設置嗎?
是的,ChromeOptions和FirefoxOptions在遠程執行時同樣適用。將相同選項傳入webdriver.Remote,Grid節點的瀏覽器即會使用該代理連接。此時IP驗證需註冊的是實際運行瀏覽器的Grid節點出口IP。
如果有多個節點,請註冊每個節點的IP。最多可註冊10個。如果雲端節點IP經常變動,為節點分配固定IP會更方便管理。
from selenium import webdriver
opts = webdriver.ChromeOptions()
opts.add_argument("--proxy-server=http://198.51.100.23:8000") # authorize the Grid node IP, not this machine
driver = webdriver.Remote(command_executor="http://grid.example.internal:4444", options=opts)
driver.get("https://api.ipify.org")
print(driver.page_source)
driver.quit()連接失敗時需要檢查什麼?
ERR_PROXY_CONNECTION_FAILED 通常是由於地址或端口錯誤。請確保沒有在 HTTP 地址中使用 SOCKS5 端口。如果出現 ERR_TUNNEL_CONNECTION_FAILED 或彈出認證窗口,可能是因為 IP 授權中註冊的 IP 與實際使用的 IP 不同。請在服務器上使用 cURL 打開 api.ipify.org 並確認實際使用的 IP,然後將其註冊。
雲端伺服器重啟後出口 IP 可能變更。請使用固定 IP,或在 IP 變更時同步更新控制台的註冊列表。