Python 通过特定的网络接口发送http请求

Python 通过特定的网络接口发送http请求,python,python-requests,Python,Python Requests,我有两个网络接口(wifi和以太网),都可以访问互联网。假设我的接口是eth(以太网)和wlp2(wifi)。我需要通过eth接口和其他通过wpl2的特定请求 比如: // Through "eth" request.post(url="http://myapi.com/store_ip", iface="eth") // Through "wlp2" request.post(url="http://myapi.com/log", iface="wlp2") 我使用的是请求,但如果没有任何

我有两个网络接口(wifi和以太网),都可以访问互联网。假设我的接口是
eth
(以太网)和
wlp2
(wifi)。我需要通过
eth
接口和其他通过
wpl2
的特定请求

比如:

// Through "eth"
request.post(url="http://myapi.com/store_ip", iface="eth")
// Through "wlp2" 
request.post(url="http://myapi.com/log", iface="wlp2")
我使用的是
请求
,但如果没有任何方法处理
请求
,我可以使用
pycurl
urllib


引用,但它不起作用。

我找到了一种使用
pycurl
的方法。这很有魅力

import pycurl
from io import BytesIO
import json


def curl_post(url, data, iface=None):
    c = pycurl.Curl()
    buffer = BytesIO()
    c.setopt(pycurl.URL, url)
    c.setopt(pycurl.POST, True)
    c.setopt(pycurl.HTTPHEADER, ['Content-Type: application/json'])
    c.setopt(pycurl.TIMEOUT, 10)
    c.setopt(pycurl.WRITEFUNCTION, buffer.write)
    c.setopt(pycurl.POSTFIELDS, data)
    if iface:
        c.setopt(pycurl.INTERFACE, iface)
    c.perform()

    # Json response
    resp = buffer.getvalue().decode('UTF-8')

    #  Check response is a JSON if not there was an error
    try:
        resp = json.loads(resp)
    except json.decoder.JSONDecodeError:
        pass

    buffer.close()
    c.close()
    return resp


if __name__ == '__main__':
    dat = {"id": 52, "configuration": [{"eno1": {"address": "192.168.1.1"}}]}
    res = curl_post("http://127.0.0.1:5000/network_configuration/", json.dumps(dat), "wlp2")
    print(res)

我把这个问题留了下来,希望有人可以使用
请求给出答案

尝试将内部IP(192.168.0.200)更改为下面代码中相应的iface

import requests
from requests_toolbelt.adapters import source

def check_ip(inet_addr):
    s = requests.Session()
    iface = source.SourceAddressAdapter(inet_addr)
    s.mount('http://', iface)
    s.mount('https://', iface)
    url = 'https://emapp.cc/get_my_ip'
    resp = s.get(url)
    print(resp.text)

if __name__ == '__main__':
    check_ip('192.168.0.200')

以下是请求库的解决方案,无需进行任何修补

此函数将创建绑定到给定IP地址的会话。由您决定所需网络接口的IP地址

经过测试,可以处理
请求==2.23.0

import requests


def session_for_src_addr(addr: str) -> requests.Session:
    """
    Create `Session` which will bind to the specified local address
    rather than auto-selecting it.
    """
    session = requests.Session()
    for prefix in ('http://', 'https://'):
        session.get_adapter(prefix).init_poolmanager(
            # those are default values from HTTPAdapter's constructor
            connections=requests.adapters.DEFAULT_POOLSIZE,
            maxsize=requests.adapters.DEFAULT_POOLSIZE,
            # This should be a tuple of (address, port). Port 0 means auto-selection.
            source_address=(addr, 0),
        )

    return session


# usage example:
s = session_for_src_addr('192.168.1.12')
s.get('https://httpbin.org/ip')

请注意,这种方法与
curl
--interface
选项相同,在某些情况下没有帮助。根据您的路由配置,即使您绑定到特定的IP地址,请求也可能会通过其他接口。因此,如果这个答案不适用于您,那么首先检查
curlhttp://httpbin.org/ip --接口myinterface
将按预期工作。

您是否找到了使用
请求的解决方案
?尚未:(…我问了一个类似的问题,现在有两个答案。有一个简单的答案不能满足我所有的需要,我找到了我自己的答案,可以实现我想要的一切。