【问题标题】:Make requests using Python over Tor在 Tor 上使用 Python 发出请求
【发布时间】:2015-07-28 23:01:42
【问题描述】:

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

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 以创建另一个?

【问题讨论】:

  • 这不是 Tor 应该做的,即混淆或以其他方式难以确定发件人的 IP 地址吗?
  • 使用词干stem.torproject.org
  • @mhawke 确实如此,但是一旦进行了连接握手,它就会在它连接的那组 IP 地址跃点中持久存在,因此操作员可能希望再次更改 IP 地址。

标签: python tor


【解决方案1】:

这是你要使用的代码(使用pip install stem下载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")

祝你好运,希望这有效。

【讨论】:

  • 我已经尝试过这个解决方案,但得到这个错误:错误(61,'连接被拒绝')。我的机器上似乎没有打开端口 9051,我在 Mac 上并且一直在尝试尽我所能找到打开此端口但仍然出现此错误。有什么想法吗?
  • @kflaw 您需要在 torrc 中取消注释您的控制端口,然后重新启动 tor。默认情况下,9051 控制端口是关闭的,因为它不需要用于常规的 tor。
  • 感谢您的回复,我忘了提到我确实取消了torrc中的控制端口以及使用哈希密码进行身份验证。我错过了什么?
  • @kflaw 您可以在 codepen 或类似的东西中发布指向您的代码的链接,以便我重复您的错误吗?谢谢
  • 这里是一个要点的链接 - 我已经尝试了几个我在类似帖子中找到的代码 sn-ps,但都在尝试建立控制端口时卡住了。 gist.github.com/kflaw/1a41654993e9692914a7fa18f8819a8f
【解决方案2】:

你的问题有两个方面-

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

第 1 部分

第一个很容易使用最新的(v2.10.0 以上)requests 库完成,另外需要 requests[socks] 才能使用 socks 代理。

安装 -

pip install 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,您需要能够通过它的 ControlPort 连接到 Tor 服务,然后发送 NEWNYM 信号。

默认情况下,普通 Tor 安装不启用 ControlPort。您必须编辑您的 torrc file 并取消注释相应的行。

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"。如果您想设置不同的密码,请注意 tor --hash-password "<new_password>" 的输出,其中 <new_password> 是您要设置的密码,替换 torrc 中的 HashedControlPassword

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

Windows 用户警告:见帖子here

如果使用以下命令安装 tor,则在 windows 上会忽略 torrc 文件中控制端口的设置:

tor --service install

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

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

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

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

sudo service tor restart

Tor 现在应该在 9051 ControlPort 上启动并运行,我们可以通过它向它发送命令。我更喜欢使用official stem library 来控制 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 并尝试重新安装)
  • @AshishNitinPatil 抱歉这个愚蠢的问题,但我们应该在哪个scrapy 文件中使用该代码? (在 settings.py、spider.py 还是其他?)
  • @JinSnow 这比 Tor 更像是一个 Scrapy 问题,请参阅 stackoverflow.com/questions/45009940/… 以获得更多帮助。
  • 我建议您使用 socks5h 以便将 DNS 解析委托给代理。
  • 要在不重新启动的情况下进行续订,您可以将 return get_tor_session() 添加到 renew_connection() 并在主代码中使用 session = renew_connection()
【解决方案3】:

requesocks 中的requests 超级旧,它没有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.
  • Requests 确实允许使用 socks 5 代理。工作正常。
【解决方案4】:

Requests supports proxies 使用 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)

【讨论】:

  • 您从不使用请求设置代理。当我使用请求 2.11 设置代理时,出现连接错误Failed to establish a new connection
  • 是的,我错过了 proxies 参数。已修复,谢谢通知。我将请求更新到 2.11 并检查了这个脚本 - 它有效。你开始tor服务了吗?如果我停下来,我会得到同样的错误。
【解决方案5】:

你可以使用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

【讨论】:

  • tr.reset_identity() 不会更改 IP 地址。我错过了什么吗?我是否需要更改 Tor 配置文件或其他内容?
  • 我知道这是一个古老的问题和答案,但这个对我有用。我只需要这样做:使用 TorRequest(proxy_port=9050, ctrl_port=9051, password='password') as tr:
  • tr.reset_identity() 对我不起作用。但无论如何,您可以创建许多 TorRequest(proxy_port=9050, ctrl_port=9051, password='password') 对象,每个新对象都会有新的 IP/会话。
【解决方案6】:

这个答案完成了 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

编辑:你会发现很多信息here(关于端口号和代理、Tor、Privoxy、自动切换用户代理...)。

【讨论】:

【解决方案7】:

此代码运行良好。使用 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()

【讨论】:

  • 这是非常棒的代码,但我很困惑 nbrOfIpAddresses=3 正在做什么。它是否开始获取固定 IP 地址列表?
  • nbrOfIpAddresses=3 只是他循环的 range() 中的第二个参数。这基本上意味着他阅读了 3 次 URL。
【解决方案8】:

您可以尝试纯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

【讨论】:

  • 你好,我需要你关于torpy的帮助如何使用socket和torpy你能帮我写一个脚本吗
  • sess.get("http....org") 工作正常,但是当我使用 sess.get("http....onion") 它给我这个错误::: : 例外:您必须先连接到保护节点
  • 如果不使用某种控制端口或 tor 服务,我根本无法让它工作。
  • 我试过这个,也得到错误“异常:您必须先连接到保护节点”
【解决方案9】:

更新IP的好功能。窗口示例

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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-26
    • 1970-01-01
    • 1970-01-01
    • 2012-06-13
    • 2016-01-13
    • 2020-04-20
    • 1970-01-01
    相关资源
    最近更新 更多