Python-stem+;请求:使用会话时不切换电路/更改IP地址

Python-stem+;请求:使用会话时不切换电路/更改IP地址,python,python-requests,tor,stem,Python,Python Requests,Tor,Stem,Cnosider下面的脚本tortest.py,它反复切换TOR电路并检查IP地址是否已更改: #!/usr/bin/env python2.7 # -*- coding: utf-8 -*- import json import time # pip install requests[socks] import requests # pip install stem from stem import Signal from stem.control import Controller

Cnosider下面的脚本
tortest.py
,它反复切换TOR电路并检查IP地址是否已更改:

#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-

import json
import time

# pip install requests[socks]
import requests

# pip install stem
from stem import Signal
from stem.control import Controller

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


def get_new_ip():
    with Controller.from_port(port=9051) as controller:
        controller.authenticate(password="xxx")
        controller.signal(Signal.NEWNYM)
        time.sleep(controller.get_newnym_wait())


for _ in xrange(5):
    get_new_ip()
    try:
        ip1 = json.loads(requests.get("https://httpbin.org/ip", timeout=(5, 5), proxies=proxies).content)["origin"]
        ip2 = json.loads(http.get("https://httpbin.org/ip", timeout=(5, 5), proxies=proxies).content)["origin"]
        print "Without session: {}".format(ip1)
        print "With session:    {}".format(ip2)
        print
    except Exception as e:
        pass
运行此脚本,我将获得以下输出:

$ python2 tortest.py
Without session: 137.74.169.241
With session:    137.74.169.241

Without session: 145.249.104.203
With session:    137.74.169.241

Without session: 5.189.170.221
With session:    137.74.169.241

Without session: 192.36.27.6
With session:    137.74.169.241

Without session: 199.249.224.43
With session:    137.74.169.241
我们可以看到,在无会话的情况下,IP地址每次都会改变。但是,在我们使用会话对象的情况下,IP地址仅在第一次请求时更改,所有后续请求都显示相同的IP地址,表明电路没有更改

为什么会发生这种情况,如何解决?如何使用
请求
会话而不丧失切换电路的能力?

这是因为

好消息-感谢urllib3,keep alive是100%自动的 在一个会话内!您在会话中提出的任何请求都将 自动重用适当的连接

请注意,连接仅释放回池以供重用 一旦读取了所有身体数据;确保将stream设置为 False或读取响应对象的内容属性

当您使用会话时,它会发送一个
连接:keep alive
标题,并将挂起连接,从而使其使用Tor中先前建立的电路

如文档中所述,您可以设置
stream=False
来绕过它:

http.get("https://httpbin.org/ip", timeout=(5, 5), proxies=proxies, stream=False)

可能为新IP创建新会话。不同IP的一个会话可能没有意义。具有新IP的用户应该从服务器获取新的Cookie等,以便启动新的、清除的会话。您是对的,保持活动状态是导致此行为的原因。但是,您的解决方案,即将
设置为
,并没有解决我的问题。它不会禁用Keep Alive(如果我正确阅读文档,它也不应该禁用Keep Alive)。为了绕过它,我必须显式地将
连接
标题设置为
关闭
。也许你想把它添加到你的答案中。@user1658887,你介意澄清一下“为了避免它,我必须显式地将连接头设置为关闭。也许你想把它添加到你的答案中”的意思吗?我只是这方面的一名学生,我很想学习如何解决这个问题