
Tor 인스턴스를 프로그래밍 방식으로 관리하는 Python 라이브러리로, SOCKS5 프록시, 아이덴티티 로테이션, 스트림 격리, 히든 서비스, 회로 제어 및 비동기 HTTP 클라이언트를 지원합니다.
Tor 인스턴스를 프로그래밍 방식으로 관리하는 Python 라이브러리입니다.
Linux (Debian/Ubuntu):
sudo apt-get install tor obfs4proxy
Windows:
torproject.org에서 Tor Expert Bundle을 다운로드하세요.
pip install xtor
# 또는
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}")
참고:
Tor.startTor()는 하위 호환성을 위해Tor.start()의 별칭으로 사용할 수 있습니다.
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) # 새 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:
# 각 키는 고유한 회로를 사용합니다
client_a = tor.isolated_client("session-a")
client_b = tor.isolated_client("session-b")
# client_a와 client_b를 통한 요청은 서로 다른 회로를 사용합니다
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}")
# 특정 회로 닫기
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}")
# 완료 후 제거
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)
# ... 작업 수행 ...
tor.remove_event_listener(on_bandwidth)
from xtor import TorPool
with TorPool(size=3, base_port=9100, password="secret") as pool:
# 라운드 로빈
tor = pool.next()
print(tor.client.get("https://api.ipify.org").text)
# 모든 ID 회전
pool.rotate_all()
# 무작위 선택
tor = pool.random()
from xtor import Tor
# 명명된 인스턴스 시작
tor = Tor.start(port=9052, control_port=9053, host="127.0.0.1", name="my-tor")
# 나중에 이름으로 다시 연결
tor = Tor.from_name("my-tor")
with tor:
print(tor.ip)
xtor CLI는 명명된 Tor 인스턴스를 백그라운드 프로세스로 관리합니다.
# 명명된 인스턴스 시작
xtor start my-tor --port 9052 --control-port 9053
# 인스턴스 목록 보기
xtor list
# 연결 세부 정보
xtor connect my-tor
# 인스턴스 중지
xtor stop my-tor
# 인스턴스 및 데이터 제거
xtor remove my-tor
XtorError (base)
├── TorNotFoundError
├── PortInUseError
├── IdentityChangeTimeout
├── ConnectionError
└── AuthenticationError
모든 예외 처리 패턴:
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}")