Complete Technical Solution for Multi-IP Address Requests Using Python and Tor

Dec 05, 2025 · Programming · 10 views · 7.8

Keywords: Python | Tor Network | IP Rotation | ControlPort | HTTP Requests

Abstract: This article provides an in-depth exploration of implementing HTTP requests through the Tor network using Python, with a focus on achieving different IP addresses for each request. It begins with the basic method of configuring SOCKS5 proxy connections to Tor using the requests library, then details how to change exit node IPs by sending NEWNYM signals through Tor's ControlPort. By analyzing core code from the best answer and incorporating supplementary approaches, the article offers complete configuration steps, code examples, and considerations to help developers implement anonymous network requests and IP rotation functionality.

Technical Background and Problem Analysis

In application scenarios such as network security, data collection, and privacy protection, making HTTP requests through the Tor network has become a common requirement. Tor (The Onion Router) effectively conceals users' real IP addresses and network activities through multi-layer encryption and distributed node forwarding. However, in practical applications, users often need finer control, such as using different exit node IP addresses for each request to avoid detection and blocking by target servers.

The code snippet presented in the original question can connect to Tor via SOCKS5 proxy but lacks an IP address rotation mechanism. This code uses the socks library to set the default proxy and then sends requests through the requests library, but this approach maintains the same Tor circuit and exit node within a single session.

Core Solution: Tor ControlPort and NEWNYM Signal

To achieve IP address rotation, the key lies in utilizing Tor's ControlPort functionality. ControlPort is a control interface provided by Tor that allows external programs to send control commands through a specific protocol. Among these, the NEWNYM signal is one of the most important commands, instructing Tor to establish a new circuit, thereby changing the exit node IP address.

First, Tor must be configured to enable ControlPort. Edit the Tor configuration file (typically located at /etc/tor/torrc or .torrc in the user directory), uncomment the following lines and set an authentication password:

ControlPort 9051
HashedControlPassword 16:05834BCEDD478D1060F1D7E2CE98E9C13075E8D3061D702F63BCD674DE

The HashedControlPassword in the above configuration corresponds to the plaintext password "password". To use a custom password, generate a new hash with the command tor --hash-password "your_password". After configuration, restart the Tor service: sudo service tor restart.

For Windows users, if Tor was installed via tor --service install, the following commands may be necessary to ensure ControlPort configuration takes effect:

tor --service remove
tor --service install -options ControlPort 9051

Detailed Python Implementation

Controlling Tor with Python requires installing the stem library, the officially recommended Python control library for Tor. Install it via: pip install stem.

The core IP rotation function is as follows:

from stem import Signal
from stem.control import Controller

def renew_tor_ip():
    with Controller.from_port(port=9051) as controller:
        controller.authenticate(password="password")
        controller.signal(Signal.NEWNYM)
        print("Tor IP address has been updated")

This function connects to Tor's ControlPort (default 9051) via Controller.from_port(), authenticates using the configured password, and then sends the NEWNYM signal. Note that the NEWNYM signal does not take effect immediately; Tor requires some time to establish a new circuit. It is generally recommended to wait a few seconds after sending the signal before initiating new requests.

The complete request flow should combine proxy configuration with the requests library:

import requests
import time

def get_tor_session():
    session = requests.Session()
    session.proxies = {
        'http': 'socks5://127.0.0.1:9050',
        'https': 'socks5://127.0.0.1:9050'
    }
    return session

# First request
session1 = get_tor_session()
response1 = session1.get("http://httpbin.org/ip")
print(f"First request IP: {response1.text}")

# Rotate IP
renew_tor_ip()
time.sleep(5)  # Wait for new circuit establishment

# New session uses new IP
session2 = get_tor_session()
response2 = session2.get("http://httpbin.org/ip")
print(f"Rotated IP: {response2.text}")

The key point is that a new requests.Session object must be created after each IP rotation. This is because existing sessions may maintain their connection pools, and even if the Tor circuit has been updated, the session might still send requests through the old circuit.

Alternative Approaches and Extended Discussion

Beyond the ControlPort-based solution, other technical paths are worth considering. The torpy library provides a pure Python implementation of the Tor protocol, eliminating the need for a native Tor client:

from torpy.http.requests import TorRequests

with TorRequests() as tor_requests:
    with tor_requests.get_session() as sess:
        print(sess.get("http://httpbin.org/ip").json())
    # Getting a new session automatically uses a new circuit
    with tor_requests.get_session() as sess:
        print(sess.get("httpbin.org/ip").json())

This method simplifies the IP rotation process by automatically changing circuits with each new session creation, but may sacrifice some performance and control precision.

In practical applications, additional considerations include: frequent IP rotation may trigger rate limits on the Tor network; some exit nodes may be blocked by target websites; and appropriate request intervals should be set to avoid overburdening the Tor network. It is advisable to balance anonymity, availability, and performance based on specific application scenarios.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.