Socks5Proxy

Python requests代理設定:SOCKS5與HTTP代理連接方法

本指南逐步講解Python requests函式庫連接Socks5Proxy的HTTP與SOCKS5代理、帳密認證、列表輪換與重試機制的實作方法。

需要準備什麼?

需Python 3.8以上與requests庫。使用SOCKS5需安裝SOCKS支援套件,安裝requests[socks]會同步安裝PySocks以支援socks5與socks5h地址。

代理資訊可在儀表板的「我的代理」頁面查看。此範例使用 IP 198.51.100.23、HTTP 端口 8000、SOCKS5 端口 1080、帳號 spx_user、密碼 spx_pass,請替換為您的實際值。

pip install "requests[socks]"

如何連接 HTTP 代理?

在 requests 的 proxies 字典中加入地址後,請求會透過該代理發送。請注意需同時設定 http 和 https 兩個鍵值為相同 HTTP 代理地址,若缺少 https 鍵值,HTTPS 請求將直接發送而不經代理。

HTTPS 網站請求全程經 CONNECT 隧道加密傳輸。以下程式碼示範透過 IP 查詢地址驗證代理 IP 是否生效。

import requests

proxy = "http://spx_user:spx_pass@198.51.100.23:8000"
proxies = {"http": proxy, "https": proxy}

r = requests.get("https://api.ipify.org?format=json", proxies=proxies, timeout=20)
print(r.status_code, r.json())  # the "ip" field should show the proxy IP

如何連接 SOCKS5 代理?

建議在地址前使用 socks5h 協議。socks5h 會讓代理端進行域名解析,避免您伺服器的 DNS 請求外洩,且解析結果基於代理所在國家。若使用 socks5,則會先在您伺服器解析域名後才將 IP 轉發給代理。

應使用 SOCKS5 端口。如果在 HTTP 端口中輸入 SOCKS5 地址,將無法連接,請注意區分每行中的兩個端口。

import requests

proxy = "socks5h://spx_user:spx_pass@198.51.100.23:1080"
proxies = {"http": proxy, "https": proxy}

r = requests.get("https://api.ipify.org?format=json", proxies=proxies, timeout=20)
print(r.json())

如何輪替使用多組代理發送請求?

採集大量頁面時,建議先獲取代理列表再輪替使用。以下代碼透過API取得SOCKS5列表依序使用,失敗請求會自動切換代理重試最多3次。為避免對同一域名請求過快,程式已加入短暫間隔。

失敗的代理不要立即丟棄,建議暫停後再使用。許多錯誤是由目標網站的狀態引起的。

import itertools
import time
import requests

API = "https://socks5proxy.io/api/v1"
KEY = "YOUR_API_KEY"

lines = requests.get(
    API + "/proxies/download",
    params={"format": "user:pass@ip:port", "protocol": "socks5"},
    headers={"Authorization": "Bearer " + KEY},
    timeout=30,
).text.split()
pool = itertools.cycle(lines)

def fetch(url, tries=3):
    for _ in range(tries):
        p = "socks5h://" + next(pool)
        try:
            r = requests.get(url, proxies={"http": p, "https": p}, timeout=20)
            if r.status_code == 200:
                return r.text
        except requests.RequestException:
            pass
        time.sleep(1)
    return None

for page in range(1, 6):
    html = fetch("https://example.com/list?page=" + str(page))
    print(page, "ok" if html else "failed")
    time.sleep(0.5)

如何維持工作階段與Cookie?

登入或分頁等需cookie連續的操作,請固定單一proxy於requests.Session實例。設置session.proxy屬性後,該session所有請求皆通過同IP發出。任務結束後關閉session,再以新proxy建立新session即可。

為每個工作階段設定固定User-Agent與Accept-Language標頭,可使目標網站看到的訪問行為更一致。

import requests

s = requests.Session()
s.proxies = {
    "http": "http://spx_user:spx_pass@198.51.100.23:8000",
    "https": "http://spx_user:spx_pass@198.51.100.23:8000",
}
s.headers.update({"User-Agent": "Mozilla/5.0", "Accept-Language": "en-US,en;q=0.9"})

s.get("https://example.com/", timeout=20)          # cookies are stored in the session
r = s.get("https://example.com/account", timeout=20)  # same IP, same cookies
print(r.status_code)
s.close()

如何使用 IP 授權連接?

在儀表板註冊執行此程式碼的伺服器IPv4後,即可省略代理地址中的帳號密碼。免除密碼寫入程式碼或設定檔的需求,更便於多伺服器部署相同程式碼。下載清單時選擇ip:port格式即可。

import requests

proxy = "http://198.51.100.23:8000"  # no user or password, server IP is authorized in the dashboard
r = requests.get("https://api.ipify.org", proxies={"http": proxy, "https": proxy}, timeout=20)
print(r.text)

如何同時快速發送多個請求?

requests 會等待單一請求完成後才繼續,若要快速擷取大量頁面,需同時執行多個任務。最簡單的方法是使用 concurrent.futures 的 ThreadPoolExecutor。建議將任務數量控制在少於代理 IP 數量,避免單一 IP 負載過高。

以下代碼將地址列表分配給 20 個工作線程,每個任務從列表中選取下一個代理使用。itertools.cycle 即使在多線程共用時也能正確取得下一個值,但若需要嚴格順序請搭配鎖定機制。

import itertools
from concurrent.futures import ThreadPoolExecutor
import requests

lines = open("proxies.txt").read().split()  # user:pass@ip:port per line
pool = itertools.cycle(lines)

def get(url):
    p = "http://" + next(pool)
    try:
        return url, requests.get(url, proxies={"http": p, "https": p}, timeout=20).status_code
    except requests.RequestException as e:
        return url, type(e).__name__

urls = ["https://example.com/item/" + str(i) for i in range(200)]
with ThreadPoolExecutor(max_workers=20) as ex:
    for url, result in ex.map(get, urls):
        print(url, result)

是否支援 httpx 或 aiohttp 等非同步函式庫?

是的。httpx在創建客戶端時,可以在proxy參數中填入地址,安裝httpx[socks]後即可使用socks5地址。異步客戶端AsyncClient也支援相同的參數。

aiohttp 需在每個請求的 proxy 參數中填入 HTTP 代理地址,並透過 proxy_auth 傳遞 aiohttp.BasicAuth。aiohttp 預設不支援 SOCKS,如需 SOCKS5 需使用 aiohttp-socks 套件的連接器。

異步模式能以少量資源同時處理數千請求,但若未限制並發請求數,可能同時衝擊目標網站與代理伺服器。建議使用asyncio.Semaphore設定並發上限。

import httpx

with httpx.Client(proxy="http://spx_user:spx_pass@198.51.100.23:8000", timeout=20) as client:
    print(client.get("https://api.ipify.org").text)

如何解決常見錯誤?

「Missing dependencies for SOCKS support」錯誤表示未安裝requests[socks],請在相同虛擬環境中重新安裝。

407 Proxy Authentication Required表示使用者名稱或密碼錯誤,或使用IP授權但伺服器IP未註冊。若密碼包含特殊字符,需使用urllib.parse.quote轉換後輸入。

連線逾時多因端口設定錯誤。HTTP地址需使用HTTP端口,socks5h地址需使用SOCKS5端口。設定timeout參數可避免無回應請求導致整個作業停滯。

  • SOCKS 錯誤:pip install "requests[socks]"
  • 407:檢查使用者名稱·密碼或註冊IP
  • 逾時:HTTP端口與SOCKS5端口的區別
  • 為所有請求設定timeout
Python requests代理設定:SOCKS5·HTTP連接 | Socks5Proxy