Как открыть несколько соединений Tor для использования в Python скриптах (на примере Ubuntu)

В предыдущем посте я показал, как можно использовать соединение Tor из Python-скрипта (а также как устанавливать и запускать Tor-сервис в Ubuntu). Преимущество того подхода (по сравнению с использованию Privoxy в качестве прослойки мeжду SOCKS и HTTP) заключается в том, что он легко масштабируется: можно открыть любое (на сколько хватит аппаратных ресурсов) количество соединений и каждому Python процессу дать по одному прокси-порту (c Privoxy это тоже можно сделать, но несколько сложнее).
Здесь же я проведу в качестве примера Bash-скрипт, который открывает заданное количество Tor-соединений и для каждого соединения запускает два Python-скрипта.
Что за два скрипта? Первый называется test_ip.py и симулирует проверку IP-адреса, который достался текущему соединению (например, проверяет, не заблокирован ли адрес на сервере). Для демонстрации я в нем просто возвращаю случайным образом 0 или 1. Вот как это выглядит:
from random import randint
import sys

sys.exit( randint( 0, 1 ) )
Второй скрипт, который называется demo_script.py делает то же, что и скрипт из предыдущего поста (выводит в консоль наш текущий IP), просто еще позволяет задавать номер прокси-порта в качестве параметра командной строки. Вот его код:
import socks
import socket
import requests
from sys import argv

socks.set_default_proxy(socks.SOCKS5, "localhost",  int( argv[ 1 ] ))
socket.socket = socks.socksocket

response = requests.get('http://icanhazip.com')
print(argv[ 1 ] + ': ' + response.text)
Ну и наконец основной Bash-скрипт: он в цикле создает новое соединение Tor и запускает скрипт test_ip.py. Если возвращаемое значение не равно 0 (то есть IP адрес "по какой-то причине" не подошел), он подключается к этому соединению через управляющий порт и просит новый IP - и так заданное число попыток (10), пока test_ip.py не вернет 0. Если этого не случилось - цикл продолжается для следующего порта. Если же test_ip.py вернул 0, в фоновом режиме запускается demo_script.py. Когда цикл завершается, скрипт ждет завершения всех задач, которые были запущены из него. Вот код получившегося скрипта:
#!/bin/bash

base_socks_port=9050 # Номер первого прокси-порта Tor
base_control_port=8118 # Номер первого управляющего порта Tor

max_tor_num=5 # Число процессов Tor, которые мы будем использовать
max_attempts_num=10 # Максимальное число попыток получить IP

# Создаем директорию tor_data для всех процессов Tor
if [ ! -d "tor_data" ]; then
    mkdir "tor_data"
fi

for tor_num in $(seq 0 $max_tor_num); do

    socks_port=$((base_socks_port+tor_num))
    control_port=$((base_control_port+tor_num))
    # Создаем директорию для текущего процесса Tor
    if [ ! -d "tor_data/tor$tor_num" ]; then
        echo "Creating directory data/tor$tor_num"
        mkdir "tor_data/tor$tor_num"
    fi

    # Запускаем Tor
    echo "Running Tor: control port = $control_port socks port = $socks_port"
    tor --RunAsDaemon 1 --CookieAuthentication 0 --HashedControlPassword "16:B572A128AA0505BA60AE89A3E492250422F21F37E18849CDD253631361" --ControlPort $control_port --PidFile tor$tor_num.pid --SocksPort $socks_port --DataDirectory tor_data/tor$tor_num

    ipOk=false

    # Проверяем IP
    for k in $(seq 0 $max_attempts_num); do
        echo "Checking ip adress (attempt $k)"
        python3 test_ip.py $socks_port 

        rc=$?
        if [ $rc -eq 0 ]; then 
            # IP в порядке, можно запускать основной скрипт в фоновом режиме
            echo "IP is fine"
            echo "Running script"
            python3 demo_script.py $socks_port &
            # Подождем 2 секунды чтобы не очень нагружать сайт, который я использую в demo_script.py
            sleep 2
            break
        else
            # IP почему-то не подошел, просим Tor сменить IP
            echo "Try another circuit"
            echo -e 'AUTHENTICATE "mypassword"\r\nsignal NEWNYM\r\nQUIT' | nc 127.0.0.1 $control_port  
            
        fi
    done
done

# Ждем, пока все python-процессы доработают
wait

# Убираем за собой
killall "tor"
rm -r "tor_data"
В консоль, помимо отладочной информации, выводятся в конечном итоге пять IP-адресов, полученных для разных прокси-портов.

Комментариев нет :

Отправить комментарий