【问题标题】:Python stem+requests: Not switching circut/changing IP address when using a sessionPython stem+requests:使用会话时不切换电路/更改 IP 地址
【发布时间】:2018-01-05 16:36:26
【问题描述】:

请考虑以下脚本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 地址,表明电路没有变化。

为什么会发生这种情况以及如何解决?如何使用request 会话而不失去切换电路的能力?

【问题讨论】:

  • 可能会为新 IP 创建新会话。不同 IP 的一个会话可能没有意义。具有新 IP 的用户应该从服务器获取新的 cookie 等,因此它应该开始新的、清除会话。

标签: python python-requests tor stem


【解决方案1】:

这是因为……

Keep-Alive

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

请注意,连接只会释放回池中以供重复使用 读取所有身体数据后;确保将流设置为 False 或读取 Response 对象的 content 属性。

当您使用会话时,它会发送一个Connection: keep-alive 标头并挂起连接,这会导致它使用之前在 Tor 中建立的电路。

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

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

【讨论】:

  • 你是对的,因为 Keep-Alive 是导致这种行为的原因。但是,您的解决方案,即将stream 设置为False,并没有解决我的问题。它不会禁用 Keep-Alive(如果我正确阅读了文档,它不应该这样做)。为了解决这个问题,我必须将Connection 标头显式设置为close。也许您想将其添加到您的答案中。
  • @user1658887,你介意澄清一下你的意思是“为了解决这个问题,我必须明确设置 Connection 标头关闭。也许你想把它添加到你的答案中。”?我只是这方面的学生,我很想学习如何解决这个问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-31
  • 2018-01-18
  • 2017-10-04
  • 2017-01-05
  • 1970-01-01
  • 2018-07-04
  • 2015-09-29
相关资源
最近更新 更多