Python词干+请求:在使用会话时不切换循环/更改IP地址

时间:2018-01-05 16:36:26

标签: 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

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个会话?

1 个答案:

答案 0 :(得分:2)

这是因为......

  

<强> 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)