Verwendung von Proxys in Python mit httpx
httpx und Proxys
httpx ist eine moderne HTTP-Bibliothek für Python, die sowohl synchrone als auch asynchrone Betriebsmodi unterstützt. Ein entscheidender Vorteil ist die integrierte Unterstützung für HTTP/2- und SOCKS-Proxys ohne zusätzliche Bibliotheken.
Installation
pip install httpx
# Für SOCKS-Unterstützung:
pip install httpx[socks]
# Für HTTP/2:
pip install httpx[http2]
Synchroner Modus
HTTP-Proxy
import httpx
proxy = "http://user:pass@proxy_ip:port"
response = httpx.get("https://httpbin.org/ip", proxy=proxy)
print(response.json())
Verschiedene Proxys für HTTP und HTTPS
proxies = {
"http://": "http://proxy1:port",
"https://": "http://proxy2:port",
}
with httpx.Client(proxy=proxies) as client:
response = client.get("https://httpbin.org/ip")
print(response.json())
SOCKS5-Proxy
import httpx
proxy = "socks5://user:pass@proxy_ip:port"
with httpx.Client(proxy=proxy) as client:
response = client.get("https://httpbin.org/ip")
print(response.json())
Asynchroner Modus
Grundlegendes Beispiel
import httpx
import asyncio
async def fetch():
proxy = "http://user:pass@proxy_ip:port"
async with httpx.AsyncClient(proxy=proxy) as client:
response = await client.get("https://httpbin.org/ip")
print(response.json())
asyncio.run(fetch())
Parallele Anfragen
import httpx
import asyncio
async def fetch_url(client, url):
try:
response = await client.get(url, timeout=10)
return response.text
except Exception as e:
return None
async def main():
proxy = "http://user:pass@proxy_ip:port"
urls = [f"https://example.com/page/{i}" for i in range(50)]
async with httpx.AsyncClient(proxy=proxy) as client:
tasks = [fetch_url(client, url) for url in urls]
results = await asyncio.gather(*tasks)
success = sum(1 for r in results if r)
print(f"Success: {success}/{len(urls)}")
asyncio.run(main())
HTTP/2 über Proxy
httpx ist eine der wenigen Python-Bibliotheken mit HTTP/2-Unterstützung:
import httpx
proxy = "http://user:pass@proxy_ip:port"
with httpx.Client(proxy=proxy, http2=True) as client:
response = client.get("https://httpbin.org/ip")
print(f"HTTP version: {response.http_version}")
print(response.json())
HTTP/2 über Proxy funktioniert über die CONNECT-Methode – der Proxy erstellt einen TCP-Tunnel, durch den eine HTTP/2-Verbindung zum Server hergestellt wird.
Proxy-Rotation
import httpx
import random
PROXIES = [
"http://user:pass@proxy1:port",
"http://user:pass@proxy2:port",
"http://user:pass@proxy3:port",
]
def get_random_proxy():
return random.choice(PROXIES)
# Synchrone Rotation
for i in range(10):
proxy = get_random_proxy()
with httpx.Client(proxy=proxy) as client:
resp = client.get("https://httpbin.org/ip")
print(resp.json())
Asynchrone Rotation
import httpx
import asyncio
import random
PROXIES = [
"http://user:pass@proxy1:port",
"http://user:pass@proxy2:port",
"http://user:pass@proxy3:port",
]
async def fetch_with_rotation(url):
proxy = random.choice(PROXIES)
async with httpx.AsyncClient(proxy=proxy) as client:
try:
resp = await client.get(url, timeout=10)
return resp.text
except Exception:
return None
async def main():
urls = ["https://example.com"] * 20
tasks = [fetch_with_rotation(url) for url in urls]
results = await asyncio.gather(*tasks)
print(f"Success: {sum(1 for r in results if r)}")
asyncio.run(main())
Client-Konfiguration
Timeout
timeout = httpx.Timeout(
connect=5.0, # Verbindung zu Proxy und Server
read=10.0, # Lesen der Antwort
write=5.0, # Senden der Anfrage
pool=5.0 # Warten im Verbindungspool
)
client = httpx.Client(proxy=proxy, timeout=timeout)
Header und Cookies
headers = {
"User-Agent": "Mozilla/5.0 ...",
"Accept-Language": "en-US,en;q=0.9",
}
client = httpx.Client(
proxy=proxy,
headers=headers,
follow_redirects=True,
max_redirects=10
)
Verbindungspool
limits = httpx.Limits(
max_connections=100, # Gesamtverbindungen
max_keepalive_connections=20 # Keep-Alive-Verbindungen
)
client = httpx.AsyncClient(proxy=proxy, limits=limits)
Fehlerbehandlung
import httpx
async def safe_fetch(client, url):
try:
response = await client.get(url)
response.raise_for_status()
return response.text
except httpx.ProxyError as e:
print(f"Proxy-Fehler: {e}")
except httpx.ConnectTimeout:
print("Verbindungs-Timeout")
except httpx.ReadTimeout:
print("Lese-Timeout")
except httpx.HTTPStatusError as e:
print(f"HTTP {e.response.status_code}")
except httpx.RequestError as e:
print(f"Anfragefehler: {e}")
return None
httpx vs requests vs aiohttp
| Parameter | httpx | requests | aiohttp |
|---|---|---|---|
| Synchron | Ja | Ja | Nein |
| Asynchron | Ja | Nein | Ja |
| HTTP/2 | Ja | Nein | Nein |
| SOCKS | Ja (integriert) | Über requests-socks | Über aiohttp-socks |
| Proxy in URL | Ja | Ja | Ja |
| API | requests-kompatibel | Standard | Benutzerdefiniert |
| Leistung | Hoch | Mittel | Hoch |
Migration von requests
httpx ist als direkter Ersatz für requests konzipiert. Die Migration ist minimal:
# requests
import requests
resp = requests.get(url, proxies={"https": proxy})
# httpx
import httpx
resp = httpx.get(url, proxy=proxy)
Der Hauptunterschied: In httpx wird der proxy-Parameter (Singular) anstelle von proxies verwendet.
Fazit
httpx ist die beste Wahl für neue Python-Projekte, die Proxy-Funktionalität benötigen. Die integrierte Unterstützung für HTTP/2, SOCKS5 sowie synchrone und asynchrone Modi macht es zu einem vielseitigen Werkzeug. Die requests-kompatible API vereinfacht die Migration für bestehende Projekte.