
Bibliothèque Python pour la gestion programmatique d'instances Tor avec proxy SOCKS5, rotation d'identité, isolation de flux, services cachés, contrôle de circuits et clients HTTP asynchrones.
Bibliothèque Python pour gérer des instances Tor par programmation.
Linux (Debian/Ubuntu) :
sudo apt-get install tor obfs4proxy
Windows :
Téléchargez le Tor Expert Bundle depuis torproject.org.
pip install xtor
# or
uv add xtor
from xtor import Tor
with Tor.start(port=9052, control_port=9053, host="127.0.0.1") as tor:
print(f"Connected through IP: {tor.ip}")
resp = tor.client.get("https://api.ipify.org")
print(resp.text)
from xtor import Tor
from xtor.exceptions import TorNotFoundError, PortInUseError
try:
with Tor.start(port=9052, control_port=9053, host="127.0.0.1", password="mypass") as tor:
print(tor.ip)
resp = tor.client.get("https://api.ipify.org")
print(resp.text)
except TorNotFoundError:
print("Tor not found on PATH")
except PortInUseError as e:
print(f"Port in use: {e}")
Remarque :
Tor.startTor()est disponible comme alias deTor.start()pour la rétrocompatibilité.
with Tor(password="mypass", port=9050, control_port=9051) as tor:
print(tor.ip)
with Tor.start(port=9052, control_port=9053, host="127.0.0.1") as tor:
print(tor.ip)
tor.new_identity(wait=True, timeout=30)
print(tor.ip) # New IP
import asyncio
from xtor import Tor
async def main():
with Tor.start(port=9052, control_port=9053, host="127.0.0.1") as tor:
async with tor.async_client as client:
resp = await client.get("https://api.ipify.org")
print(resp.text)
asyncio.run(main())
with Tor.start(port=9052, control_port=9053, host="127.0.0.1") as tor:
# Each key gets its own circuit
client_a = tor.isolated_client("session-a")
client_b = tor.isolated_client("session-b")
# Requests through client_a and client_b use different circuits
with Tor.start(port=9052, control_port=9053, host="127.0.0.1") as tor:
circuits = tor.get_circuits()
for c in circuits:
print(f"Circuit {c.id}: {c.status}, path: {c.path}")
# Close a specific circuit
tor.close_circuit(circuits[0].id)
with Tor.start(port=9052, control_port=9053, host="127.0.0.1") as tor:
info = tor.exit_node
if info:
print(f"Exit: {info.nickname} ({info.country})")
print(f"Flags: {info.flags}")
with Tor.start(port=9052, control_port=9053, host="127.0.0.1") as tor:
service = tor.create_hidden_service({80: 8080})
print(f"Service: {service.onion_address}")
# Remove when done
tor.remove_hidden_service(service)
with Tor.start(port=9052, control_port=9053, host="127.0.0.1") as tor:
def on_bandwidth(event):
print(f"Read: {event.read}, Written: {event.written}")
tor.add_event_listener("BW", on_bandwidth)
# ... do work ...
tor.remove_event_listener(on_bandwidth)
from xtor import TorPool
with TorPool(size=3, base_port=9100, password="secret") as pool:
# Round-robin
tor = pool.next()
print(tor.client.get("https://api.ipify.org").text)
# Rotate all identities
pool.rotate_all()
# Random selection
tor = pool.random()
from xtor import Tor
# Start named instance
tor = Tor.start(port=9052, control_port=9053, host="127.0.0.1", name="my-tor")
# Later, reconnect by name
tor = Tor.from_name("my-tor")
with tor:
print(tor.ip)
La CLI xtor gère les instances Tor nommées en tant que processus d'arrière-plan.
# Start a named instance
xtor start my-tor --port 9052 --control-port 9053
# List instances
xtor list
# Connection details
xtor connect my-tor
# Stop instance
xtor stop my-tor
# Remove instance and data
xtor remove my-tor
XtorError (base)
├── TorNotFoundError
├── PortInUseError
├── IdentityChangeTimeout
├── ConnectionError
└── AuthenticationError
Modèle de capture globale :
from xtor.exceptions import XtorError
try:
with Tor.start(port=9052, control_port=9053, host="127.0.0.1") as tor:
...
except XtorError as e:
print(f"xtor error: {e}")