当前位置: 首页 > 面试题库 >

如何使用请求库从http请求中获取IP地址?

蓟捷
2023-03-14
问题内容

我正在使用python中的请求库发出HTTP请求,但我需要来自响应http请求的服务器的IP地址,因此,我试图避免进行两次调用(可能与响应的IP地址不同)请求。

那可能吗?是否有任何python http库允许我这样做?

ps:我还需要发出HTTPS请求并使用经过身份验证的代理。

更新1:

例:

import requests

proxies = {
  "http": "http://user:password@10.10.1.10:3128",
  "https": "http://user:password@10.10.1.10:1080",
}

response = requests.get("http://example.org", proxies=proxies)
response.ip # This doesn't exist, this is just an what I would like to do

然后,我想知道响应中的方法或属性将哪些IP地址请求连接到了。在其他库中,我可以通过找到袜子对象并使用getpeername()方法来做到这一点。


问题答案:

事实证明,它涉及其中。

这是使用requests1.2.3版时的一个猴子补丁:

包装_make_request方法HTTPConnectionPool以存储实例socket.getpeername()上的响应HTTPResponse

对我而言,在python 2.7.3上,该实例在上可用response.raw._original_response

from requests.packages.urllib3.connectionpool import HTTPConnectionPool

def _make_request(self,conn,method,url,**kwargs):
    response = self._old_make_request(conn,method,url,**kwargs)
    sock = getattr(conn,'sock',False)
    if sock:
        setattr(response,'peer',sock.getpeername())
    else:
        setattr(response,'peer',None)
    return response

HTTPConnectionPool._old_make_request = HTTPConnectionPool._make_request
HTTPConnectionPool._make_request = _make_request

import requests

r = requests.get('http://www.google.com')
print r.raw._original_response.peer

产量:

('2a00:1450:4009:809::1017', 80, 0, 0)

嗯,如果涉及代理或响应被分块,HTTPConnectionPool._make_request则不会调用该代理。

因此,这里有一个新版本的补丁程序httplib.getresponse

import httplib

def getresponse(self,*args,**kwargs):
    response = self._old_getresponse(*args,**kwargs)
    if self.sock:
        response.peer = self.sock.getpeername()
    else:
        response.peer = None
    return response


httplib.HTTPConnection._old_getresponse = httplib.HTTPConnection.getresponse
httplib.HTTPConnection.getresponse = getresponse

import requests

def check_peer(resp):
    orig_resp = resp.raw._original_response
    if hasattr(orig_resp,'peer'):
        return getattr(orig_resp,'peer')

运行:

>>> r1 = requests.get('http://www.google.com')
>>> check_peer(r1)
('2a00:1450:4009:808::101f', 80, 0, 0)
>>> r2 = requests.get('https://www.google.com')
>>> check_peer(r2)
('2a00:1450:4009:808::101f', 443, 0, 0)
>>> r3 = requests.get('http://wheezyweb.readthedocs.org/en/latest/tutorial.html#what-you-ll-build')
>>> check_peer(r3)
('162.209.99.68', 80)

还检查了是否设置了代理运行;返回代理地址。

更新 2016/01/19

est提供了不需要monkey-patch的替代方法:

rsp = requests.get('http://google.com', stream=True)
# grab the IP while you can, before you consume the body!!!!!!!!
print rsp.raw._fp.fp._sock.getpeername()
# consume the body, which calls the read(), after that fileno is no longer available.
print rsp.content

更新 2016/05/19

从评论中复制到此处以提高可见性,Richard KennethNiescior提供了以下已确认可用于请求2.10.0和Python 3的内容。

rsp=requests.get(..., stream=True)
rsp.raw._connection.sock.getpeername()

更新 2019/02/22

要求版本为2.19.1的Python3。

resp=requests.get(..., stream=True)
resp.raw._connection.sock.socket.getsockname()

更新 2020/01/31

带有请求2.22.0的Python3.8

resp = requests.get('https://www.google.com', stream=True)
resp.raw._connection.sock.getsockname()


 类似资料:
  • 得到的结果为: 从请求中提取的最佳方法是什么?

  • 我在Tomcat 7上使用Spring 4 MVC实现RESTful Web服务。 想知道如果外部客户端发送HTTP请求,是否有办法在服务器端层中获取特定客户端的IP地址?

  • 本文向大家介绍php如何获取Http请求,包括了php如何获取Http请求的使用技巧和注意事项,需要的朋友参考一下 php获取Http请求的方法 $_SERVER介绍 $_SERVER是一个包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组。 获取Http请求的方法示例 实例补充: socket方式 使用套接字建立连接,拼接 HTTP

  • 问题内容: 我正在尝试让我的函数返回http get请求,但是,无论如何,它似乎在?scope中丢失了。我对Node.js不熟悉,因此不胜感激 问题答案: 当然,您的日志会返回:您在完成请求之前先进行日志。问题不是范围,而是 异步性 。 是异步的,这就是为什么它将回调作为参数的原因。做您在回调中要做的事情(传递给的):

  • 问题内容: 我注意到某些站点的IP命中率有限,因此我可以通过编程使他们感到请求不是来自同一IP的, 好吧,我不太确定abot HTTP数据包,但是我们可以在标头或某个地方指定它以使其变得愚蠢吗? 这是GET请求的代码 问题答案: 我猜想该过滤器是在IP数据包级别而不是更高级别的HTTP级别应用的。在这种情况下, 是和否 。 是的-从技术上来说,可以欺骗您的IP地址,以便IP数据包看起来像来自其他地

  • 我的安全配置有问题,我需要创建一个访问我的应用程序的IP列表。 我的问题是以动态的方式为我的所有应用程序请求获取Ip。但是我不想为我的应用程序的所有请求添加一个HttpServletRequest,我想要的是一个在每个请求之前调用的方法,甚至在SecurityConfig事件之前。 我尝试在我的控制器类中自动生成它,但我的应用程序没有执行。我该怎么做才能让这件事成功?