在Tor上使用Python发出请求


77

我想使用Tor向网页发出多个GET请求。我想为每个请求使用不同的ipaddress。

import socks
import socket
socks.set_default_proxy(socks.SOCKS5, "127.0.0.1", 9150)
socket.socket = socks.socksocket
import requests
print (requests.get('http://icanhazip.com')).content

使用此,我提出了一个请求。如何更改ipaddress来做另一个?


那不是应该做什么,即混淆或以其他方式使发送者的IP地址难以确定吗?
mhawke,2015年


@mhawke可以,但是一旦建立了连接握手,它就会在连接的那组ip地址跳中保持不变,这就是为什么op希望再次更改ip地址的原因。
jamescampbell '16

Answers:


35

这是您要使用的代码(使用来下载词干包pip install stem

from stem import Signal
from stem.control import Controller

with Controller.from_port(port = 9051) as controller:
    controller.authenticate(password='your password set for tor controller port in torrc')
    print("Success!")
    controller.signal(Signal.NEWNYM)
    print("New Tor connection processed")

祝你好运,希望能成功。


我已经尝试过此解决方案,但收到此错误:error(61,'拒绝连接')。看来我的计算机上未打开端口9051,我在Mac上并且一直在尽我所能打开该端口,但仍然遇到此错误。有任何想法吗?
kflaw

1
@kflaw您需要取消注释torrc中的控制端口,然后重新启动tor。默认情况下,9051控制端口已关闭,因为常规Tor不需要使用该端口。
jamescampbell

感谢您的答复,我忘了提到我没有注释torrc中的控制端口以及使用哈希密码进行身份验证。我想念什么?
kflaw

@kflaw您可以在Codepen或类似的代码中发布指向您代码的链接,以便我可以重复您的错误吗?谢谢
jamescampbell '17

这是要点的链接-我尝试了在类似的帖子中找到的几个代码段,但是所有代码段都试图建立控制端口。gist.github.com/kflaw/1a41654993e9692914a7fa18f8819a8f
kflaw

109

您的问题有两个方面-

  1. 使用Tor发出请求
  2. 根据要求更新连接(在您的情况下,在每次请求之后)

第1部分

第一个易于使用最新(v2.10.0或更高版本)的requests库来完成,另外还需要requests[socks]使用socks代理。

安装-

pip install requests requests[socks]

基本用法-

import requests

def get_tor_session():
    session = requests.session()
    # Tor uses the 9050 port as the default socks port
    session.proxies = {'http':  'socks5://127.0.0.1:9050',
                       'https': 'socks5://127.0.0.1:9050'}
    return session

# Make a request through the Tor connection
# IP visible through Tor
session = get_tor_session()
print(session.get("http://httpbin.org/ip").text)
# Above should print an IP different than your public IP

# Following prints your normal public IP
print(requests.get("http://httpbin.org/ip").text)

第2部分

要更新Tor IP,即拥有一个新的可见退出IP,您需要能够通过Tor IP连接到Tor服务ControlPort,然后发送NEWNYM信号。

ControlPort默认情况下,正常Tor安装不会启用。您必须编辑torrc文件并取消注释相应的行。

ControlPort 9051
## If you enable the controlport, be sure to enable one of these
## authentication methods, to prevent attackers from accessing it.
HashedControlPassword 16:05834BCEDD478D1060F1D7E2CE98E9C13075E8D3061D702F63BCD674DE

请注意,HashedControlPassword以上是密码"password"。如果要设置其他密码,请HashedControlPassword注意以下位置的输出,以替换torrctor --hash-password "<new_password>"中的<new_password>是您要设置的密码。

................................................... ....................................

Windows用户警告:请参阅此处的帖子。

在Windows上存在一个问题,如果使用以下命令安装了tor,则torrc文件中的控制端口设置将被忽略:

tor --service install

要解决此问题,请在编辑torrc文件后,键入以下命令:

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

................................................... ....................................

好的,现在我们已经正确配置了Tor,如果Tor已经在运行,则必须重新启动它。

sudo service tor restart

Tor现在应该在9051上启动并运行ControlPort,我们可以通过它向其发送命令。我更喜欢使用官方的词干库来控制Tor。

安装-

pip install stem

您现在可以通过调用以下函数来更新Tor IP。

续订IP -

from stem import Signal
from stem.control import Controller

# signal TOR for a new connection 
def renew_connection():
    with Controller.from_port(port = 9051) as controller:
        controller.authenticate(password="password")
        controller.signal(Signal.NEWNYM)

要验证Tor具有新的退出IP,只需重新运行第1部分中的代码。出于我不知道的某些原因,您需要创建一个新session对象才能使用新IP。

session = get_tor_session()
print(session.get("http://httpbin.org/ip").text)

part1(进行测试),您将需要pip install request[socks](如果遇到错误,pip uninstall request然后尝试重新安装)
JinSnow

@AshishNitinPatil对于这个愚蠢的问题感到抱歉,但是我们应该在哪个scrapy文件中使用该代码?(在settings.py中,还是spider.py还是其他?)
JinSnow

1
@JinSnow与Tor相比,这更是一个棘手的问题,请参见stackoverflow.com/questions/45009940/…以获取更多帮助。
shad0w_wa1k3r 17-10-28

17

您可以使用torrequest库(无耻的插件)。在PyPI上可用。

from torrequest import TorRequest

with TorRequest() as tr:
  response = tr.get('http://ipecho.net/plain')
  print(response.text)  # not your IP address

  tr.reset_identity()

  response = tr.get('http://ipecho.net/plain')
  print(response.text)  # another IP address, not yours

3
tr.reset_identity()不会更改IP地址。我想念什么吗?我是否需要更改Tor配置文件或其他内容?
Shivam Gaur

4
我知道这是一个古老的问答,但这对我有用。我只需要这样做:用TorRequest(proxy_port = 9050,ctrl_port = 9051,password ='password')as tr:
Alex

1
tr.reset_identity()对我不起作用。但是无论如何,您可以创建许多<code> TorRequest(proxy_port = 9050,ctrl_port = 9051,password ='password')<code>对象,每个新对象将具有新的IP /会话。
Timur Nurlygayanov

在Windows上对我不起作用
OfirD

9

您可以尝试使用纯Python Tor协议实现Torpy。完全不需要原始的Tor客户端或Stem依赖项。

$ pip3 install torpy[requests]
...

$ python3.7
>>> from torpy.http.requests import TorRequests
>>> with TorRequests() as tor_requests:
...    print("build circuit")
...    with tor_requests.get_session() as sess:
...        print(sess.get("http://httpbin.org/ip").json())
...        print(sess.get("http://httpbin.org/ip").json())
...    print("renew circuit")
...    with tor_requests.get_session() as sess:
...        print(sess.get("http://httpbin.org/ip").json())
...        print(sess.get("http://httpbin.org/ip").json())
...
build circuit
{'origin': '23.129.64.190, 23.129.64.190'}
{'origin': '23.129.64.190, 23.129.64.190'}
renew circuit
{'origin': '198.98.50.112, 198.98.50.112'}
{'origin': '198.98.50.112, 198.98.50.112'}

因此,每次获得新会话时,您都会获得新身份(基本上,您将获得具有新出口节点的新电路)。在自述文件https://github.com/torpyorg/torpy中查看更多示例


7

请求使用2.10.0版以上的SOCKS协议支持代理

import requests
proxies = {
    'http': 'socks5://localhost:9050',
    'https': 'socks5://localhost:9050'
}
url = 'http://httpbin.org/ip'
print(requests.get(url, proxies=proxies).text)

1
您永远不会为请求设置代理。当我用请求2.11设置代理时,出现连接错误Failed to establish a new connection
user193661 '16

1
是的,我错过了代理参数。已修复,感谢您的通知。我将请求更新为2.11并检查了此脚本-它可以工作。您是否开始了tor服务?如果我停止tor,则会收到相同的错误。
卡里莫夫·德米特里

4

该答案完成了Windows的Ashish Nitin Patil之一 (随时更新此答案)

第2部分

ControlPort 9051
## If you enable the controlport, be sure to enable one of these
## authentication methods, to prevent attackers from accessing it.
HashedControlPassword 16:05834BCEDD478D1060F1D7E2CE98E9C13075E8D3061D702F63BCD674DE

HashedControlPassword上面的密码。如果要在控制台中设置其他密码,请浏览\Tor Browser\Browser\TorBrowser\Tor并键入以下命令:)tor.exe --hash-password password_XYZ | more。它将给您类似“HashedControlPassword 16:54C092A8...这是您的密码”的信息。现在,您可以将其添加到torrc文件(Tor Browser\Browser\TorBrowser\Data\Tor\torrc)。

然后,您将需要重新启动Tor:

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

要检查是否可以输入 netstat -an是否您现在将看到端口9051已打开。

注意,tor --service install -...将创建Tor Win32 Service。由于某种原因,您似乎必须停止使用浏览器的服务(运行services.msc

编辑:您将在这里找到许多信息(关于端口号和代理,Tor,Privoxy,自动切换用户代理...)。


1
更多信息在这里:github.com/WiliTest/...
J.确实

3

此代码可以正常工作。使用Tor,它会在每次请求后更改IP地址。

import time, socks, socket
from urllib2 import urlopen
from stem import Signal
from stem.control import Controller

nbrOfIpAddresses=3

with Controller.from_port(port = 9051) as controller:
   controller.authenticate(password = 'my_pwd')
   socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", 9050)
   socket.socket = socks.socksocket   

   for i in range(0, nbrOfIpAddresses):
       newIP=urlopen("http://icanhazip.com").read()
       print("NewIP Address: %s" % newIP)
       controller.signal(Signal.NEWNYM)
       if controller.is_newnym_available() == False:
        print("Waitting time for Tor to change IP: "+ str(controller.get_newnym_wait()) +" seconds")
        time.sleep(controller.get_newnym_wait())
   controller.close()

1
这确实是很棒的代码,但是我对此感到困惑nbrOfIpAddresses=3。它开始获取固定IP地址的列表吗?
user321627

1

requestsrequesocks是超级老,它不具备response.json()和许多其他的东西。

我想保持我的代码干净。但是,requests目前尚不支持socks5(有关更多详细信息,请阅读此线程https://github.com/kennethreitz/requests/pull/478

所以我现在用作Privoxy连接Tor的http代理。

在Mac上安装和配置Privoxy

brew install privoxy
vim /usr/local/etc/privoxy/config
# put this line in the config
forward-socks5 / localhost:9050 .
privoxy /usr/local/etc/privoxy/config

在Ubuntu上安装和配置Privoxy

sudo apt-get install privoxy
sudo vim /etc/privoxy/config
# put this line in the config
forward-socks5 / localhost:9050 .
sudo /etc/init.d/privoxy restart

现在,我可以像HTTP代理一样使用Tor。以下是我的python脚本。

import requests

proxies = {
  'http': 'http://127.0.0.1:8118',
}

print requests.get('http://httpbin.org/ip', proxies=proxies).text

在osx上,最后一行privoxy /usr/local/etc/privoxy/config返回此错误2016-08-06 23:47:01.761 00000048 Error: Wrong number of parameters for forward-socks5 in configuration file.
Shoham

请求确实允许使用socks 5代理。工作正常。
jamescampbell '16

0

续订IP的良好功能。Windows示例

def renew_tor_ip():
    with Controller.from_port(port = 9051) as controller:
        controller.authenticate(password="aAjkaI19!!laksjd")
        controller.signal(Signal.NEWNYM)

使用例

import requests
import time
from stem import Signal
from stem.control import Controller


def get_current_ip():
    session = requests.session()

    # TO Request URL with SOCKS over TOR
    session.proxies = {}
    session.proxies['http']='socks5h://localhost:9150'
    session.proxies['https']='socks5h://localhost:9150'

    try:
        r = session.get('http://httpbin.org/ip')
    except Exception as e:
        print(str(e))
    else:
        return r.text

#16:8EE7AEE3F32EEEEB605C6AA6C47B47808CA6A81FA0D76546ADC05F0F15 to aAjkaI19!!laksjd
#cmd shell "C:\Users\Arthur\Desktop\Tor Browser\Browser\TorBrowser\Tor\tor.exe" --hash-password aAjkaI19!!laksjd | more
#Torcc config
#ControlPort 9051
#HashedControlPassword 16:8EE7AEE3F32EEEEB605C6AA6C47B47808CA6A81FA0D76546ADC05F0F15

def renew_tor_ip():
    with Controller.from_port(port = 9051) as controller:
        controller.authenticate(password="aAjkaI19!!laksjd")
        controller.signal(Signal.NEWNYM)


for i in range(5):
    print(get_current_ip())
    renew_tor_ip()
    time.sleep(5)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.