Cần chuẩn bị những gì?
Bạn cần Python 3.8 trở lên và thư viện requests. Để sử dụng SOCKS5, bạn cần cài đặt gói hỗ trợ SOCKS cùng lúc. Cài đặt requests[socks] sẽ tự động cài đặt PySocks và cho phép bạn sử dụng địa chỉ socks5 và socks5h.
Thông tin proxy có trong màn hình 'Proxy của tôi' trên bảng điều khiển. Ví dụ này sử dụng IP 198.51.100.23, cổng HTTP 8000, cổng SOCKS5 1080, tên người dùng spx_user, mật khẩu spx_pass. Hãy thay bằng giá trị thực của bạn.
pip install "requests[socks]"Làm thế nào để kết nối HTTP proxy?
requests sẽ gửi yêu cầu qua proxy khi bạn thêm địa chỉ vào từ điển proxies. Điều quan trọng là thêm cùng một địa chỉ HTTP proxy vào cả hai khóa http và https. Nếu không có khóa https, các yêu cầu HTTPS sẽ không đi qua proxy mà đi thẳng ra ngoài.
Yêu cầu trang HTTPS đi qua proxy bằng phương thức CONNECT, với nội dung được mã hóa từ đầu đến cuối. Đoạn mã dưới đây là ví dụ kiểm tra xem IP proxy có xuất hiện trong phản hồi từ địa chỉ kiểm tra IP hay không.
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 IPLàm thế nào để kết nối proxy SOCKS5?
SOCKS5 khuyến nghị sử dụng socks5h trước địa chỉ. socks5h phân giải tên miền từ phía proxy, giúp yêu cầu DNS từ máy chủ của bạn không bị lộ ra ngoài và tên miền được phân giải dựa trên quốc gia của proxy. socks5 sẽ phân giải tên miền từ máy chủ của bạn trước khi gửi IP đến proxy.
Bạn phải sử dụng cổng SOCKS5. Không thể kết nối bằng cách nhập địa chỉ SOCKS5 vào cổng HTTP, vì vậy hãy phân biệt hai cổng trên mỗi dòng.
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())Làm thế nào để luân phiên nhiều proxy khi gửi yêu cầu?
Khi thu thập nhiều trang, cách cơ bản là nhận danh sách proxy và sử dụng proxy tiếp theo cho mỗi yêu cầu. Đoạn mã dưới đây nhận danh sách SOCKS5 qua API và sử dụng lần lượt, đồng thời thử lại tối đa 3 lần với proxy khác nếu yêu cầu thất bại. Nó cũng có thời gian nghỉ ngắn để tránh gửi yêu cầu quá nhanh đến cùng một tên miền.
Thay vì loại bỏ proxy lỗi ngay, hãy cho nó nghỉ một lúc rồi dùng lại. Lỗi tạm thời thường do trạng thái trang đích.
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)Làm cách nào để duy trì phiên và cookie?
Đối với các luồng yêu cầu liên tục như đăng nhập hoặc chuyển trang, hãy sử dụng một proxy cố định với một requests.Session. Đặt địa chỉ proxy vào thuộc tính proxies của đối tượng session để tất cả các yêu cầu từ session đó đều đi qua cùng một IP. Khi luồng kết thúc, hãy đóng session và tạo một session mới với proxy tiếp theo.
Cố định header User-Agent và Accept-Language cho mỗi phiên giúp hình ảnh hiển thị trên site đích ổn định.
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()Cách dùng khi kết nối bằng xác thực IP?
Khi bạn đăng ký IPv4 của máy chủ chạy mã này trên bảng điều khiển, bạn có thể sử dụng địa chỉ mà không cần tên người dùng và mật khẩu. Bạn không cần lưu mật khẩu trong mã hoặc tệp cấu hình, giúp dễ dàng triển khai cùng một mã trên nhiều máy chủ. Bạn cũng có thể chọn định dạng ip:port khi nhận danh sách.
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)Làm thế nào để gửi nhiều yêu cầu đồng thời một cách nhanh chóng?
requests là phương thức chờ đến khi một yêu cầu hoàn thành, vì vậy để nhận nhiều trang nhanh chóng, bạn cần chạy nhiều tác vụ đồng thời. Cách dễ nhất là sử dụng ThreadPoolExecutor từ concurrent.futures. Đặt số lượng tác vụ ít hơn số lượng proxy để tránh tập trung yêu cầu vào một IP.
Mã dưới đây chia danh sách địa chỉ thành 20 phần và mỗi tác vụ chọn proxy tiếp theo từ danh sách để sử dụng. itertools.cycle không gặp vấn đề khi lấy giá trị tiếp theo ngay cả khi được sử dụng cùng lúc bởi nhiều luồng, nhưng nếu cần thứ tự chính xác, hãy sử dụng khóa.
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)Có thể sử dụng các thư viện không đồng bộ như httpx hoặc aiohttp không?
Đúng vậy. httpx cho phép bạn thêm địa chỉ proxy vào tham số proxy khi tạo client, và cài đặt httpx[socks] để sử dụng địa chỉ socks5. AsyncClient cũng hỗ trợ cùng một tham số.
aiohttp yêu cầu thêm địa chỉ proxy HTTP vào tham số proxy, và proxy_auth với aiohttp.BasicAuth. aiohttp không hỗ trợ SOCKS mặc định, nếu cần SOCKS5 phải dùng connector từ gói aiohttp-socks.
Phương thức bất đồng bộ xử lý hàng ngàn yêu cầu cùng lúc với ít tài nguyên, nhưng nếu không giới hạn số yêu cầu đồng thời sẽ gây quá tải trang đích và proxy. Dùng asyncio.Semaphore để giới hạn số yêu cầu đồng thời.
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)Làm thế nào để giải quyết các lỗi thường gặp?
Lỗi thiếu phụ thuộc cho hỗ trợ SOCKS có nghĩa là requests[socks] chưa được cài đặt. Hãy cài đặt lại trong cùng môi trường ảo.
407 Proxy Authentication Required xảy ra khi sai tên người dùng/mật khẩu hoặc sử dụng IP authorization nhưng chưa đăng ký IP máy chủ. Nếu mật khẩu có ký tự đặc biệt, cần mã hóa bằng urllib.parse.quote.
Hết thời gian kết nối thường do sai port. Hãy đảm bảo sử dụng port HTTP cho địa chỉ HTTP và port SOCKS5 cho địa chỉ socks5h. Thêm giá trị timeout sẽ ngăn yêu cầu không phản hồi làm dừng toàn bộ tác vụ.
- Lỗi SOCKS: pip install "requests[socks]"
- 407: Kiểm tra tên người dùng/mật khẩu hoặc IP đã đăng ký
- Hết thời gian: Phân biệt cổng HTTP và SOCKS5
- Thêm timeout cho mọi yêu cầu