我有两个网络接口(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")
我正在使用requests
,但如果pycurl
没有任何办法,我可以使用urllib
或requests
。
How to specify source interface in python requests module?引用Requests, bind to an ip,但不起作用。
答案 0 :(得分:6)
这是没有猴子修补任何内容的Requests库的解决方案。
此功能将创建一个绑定到给定IP地址的会话。由您决定所需网络接口的IP地址。
经过测试可与requests==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
的{{1}}选项相同,但在某些情况下无济于事。根据您的路由配置,即使您绑定到特定的IP地址,请求也可能会通过其他接口发生。因此,如果此答案对您不起作用,请首先检查--interface
是否可以按预期工作。
答案 1 :(得分:3)
我找到了使用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)
我离开问题时,有人可以使用requests
给出答案。
答案 2 :(得分:-1)
尝试在下面的代码中将内部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')