การตั้งค่า proxy ใน Python requests เชื่อมต่อ SOCKS5 และ HTTP proxy
คู่มือนี้จะอธิบายวิธีการเชื่อมต่อ HTTP Proxy และ SOCKS5 Proxy ของ Socks5Proxy ด้วยไลบรารี Python requests การรับรอง username และ password รหัสสำหรับหมุนเวียนรายการและลองใหม่เป็นขั้นตอน
ต้องเตรียมอะไรบ้าง?
ต้องใช้ 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]"How to connect to an HTTP proxy?
requests จะส่งคำขอผ่านพร็อกซี่เมื่อเพิ่มที่อยู่ในพจนานุกรม proxies การเพิ่มที่อยู่พร็อกซี่ HTTP เดียวกันในทั้งคีย์ http และ https เป็นสิ่งสำคัญ หากไม่มีคีย์ https คำขอไปยังที่อยู่ HTTPS จะไม่ผ่านพร็อกซี่แต่จะส่งออกไปโดยตรง
HTTPS site requests pass through the proxy via the CONNECT method, with content encrypted end-to-end. The code below requests an IP check address to verify if the proxy IP appears in the response.
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 Proxy อย่างไร
แนะนำให้ใช้ socks5h นำหน้าที่อยู่ socks5h อนุญาตให้ตรวจสอบชื่อโดเมนทางฝั่งพร็อกซี เพื่อป้องกันไม่ให้คำขอ DNS ของเซิร์ฟเวอร์คุณรั่วไหลออกไป และโดเมนจะถูกแก้ไขตามประเทศของพร็อกซี หากใช้ socks5 การตรวจสอบชื่อโดเมนจะเกิดขึ้นที่เซิร์ฟเวอร์ของคุณก่อนส่งเฉพาะ IP ไปยังพร็อกซี
ต้องใช้พอร์ต SOCKS5 การใส่ที่อยู่ SOCKS5 ในพอร์ต HTTP จะทำให้ไม่สามารถเชื่อมต่อได้ โปรดแยกสองพอร์ตในแต่ละบรรทัด
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())วิธีการหมุนเวียนใช้พร็อกซีหลายตัวสำหรับการส่งคำขอ?
เมื่อเก็บข้อมูลจากหลายหน้า วิธีพื้นฐานคือรับรายการและใช้พร็อกซี่ถัดไปสำหรับแต่ละคำขอ รหัสด้านล่างรับรายการ SOCKS5 ผ่าน API และใช้แบบวนรอบ พร้อมลองคำขอที่ล้มเหลวใหม่สูงสุด 3 ครั้งด้วยพร็อกซี่อื่น และมีการหยุดพักสั้นๆ เพื่อไม่ส่งคำขอไปยังโดเมนเดียวกันเร็วเกินไป
ควรพัก proxy ที่ล้มเหลวสักครู่ก่อนใช้ใหม่มากกว่าจะทิ้งไปทันที เนื่องจากข้อผิดพลาดชั่วคราวมักเกิดจากสถานะของเว็บไซต์เป้าหมาย
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)วิธีการรักษาเซสชันและคุกกี้?
สำหรับกระบวนการที่ต้องใช้คุกกี้ต่อเนื่อง เช่น การเข้าสู่ระบบหรือการเปลี่ยนหน้า ให้ใช้ requests.Session หนึ่งตัวกับ Proxy หนึ่งตัว กำหนดที่อยู่ Proxy ในคุณสมบัติ proxies ของเซสชัน เพื่อให้คำขอทั้งหมดจากเซสชันนั้นใช้ IP เดียวกัน เมื่อกระบวนการเสร็จสิ้น ให้ปิดเซสชันและสร้างเซสชันใหม่กับ Proxy ตัวถัดไป
หากกำหนด 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 รอจนกว่าคำขอหนึ่งจะเสร็จสิ้นก่อนที่จะดำเนินการต่อ การดาวน์โหลดหลายหน้าอย่างรวดเร็วต้องรันหลายงานพร้อมกัน วิธีที่ง่ายที่สุดคือใช้ ThreadPoolExecutor จาก concurrent.futures การรักษาจำนวนงานให้น้อยกว่าจำนวนพร็อกซี่จะป้องกันไม่ให้คำขอมากเกินไปใน 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 ต้องใส่ที่อยู่ HTTP Proxy ในอาร์กิวเมนต์ proxy สำหรับแต่ละคำขอ และส่ง aiohttp.BasicAuth ไปยัง proxy_auth aiohttp ไม่รองรับ SOCKS โดยค่าเริ่มต้น ดังนั้นหากต้องการใช้ SOCKS5 คุณต้องใช้คอนเนคเตอร์จากแพ็คเกจ aiohttp-socks
วิธีการแบบอะซิงโครนัสสามารถประมวลผลคำขอหลายพันรายการพร้อมกันด้วยทรัพยากรน้อย แต่หากไม่จำกัดจำนวนคำขอพร้อมกันอาจทำให้เว็บไซต์เป้าหมายและ proxy รับภาระหนัก ใช้ 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 authorization แต่ไม่ได้ลงทะเบียน IP ของเซิร์ฟเวอร์ หากรหัสผ่านมีอักขระพิเศษ ต้องแปลงด้วย urllib.parse.quote ก่อนนำมาใช้
การเชื่อมต่อหมดเวลาส่วนใหญ่เกิดจากการใช้พอร์ตไม่ตรงกัน ตรวจสอบว่าคุณใช้พอร์ต HTTP สำหรับที่อยู่ HTTP และพอร์ต SOCKS5 สำหรับที่อยู่ socks5h การกำหนดค่า timeout จะช่วยป้องกันไม่ให้คำขอที่ไม่มีตอบสนองหยุดการทำงานทั้งหมด
- SOCKS Error: pip install "requests[socks]"
- 407: ตรวจสอบชื่อผู้ใช้·รหัสผ่าน หรือ IP ที่ลงทะเบียน
- หมดเวลา: แยกพอร์ต HTTP และ SOCKS5
- เพิ่ม timeout ในทุกคำขอ