You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python发送REST GET请求时如何指定客户端端口?

如何在Python Requests库中指定客户端端口发起GET请求

你说的完全没错——默认情况下,Python的socket客户端发起连接时,系统会从空闲的动态端口范围里随机分配一个源端口,requests库底层依赖socket实现HTTP请求,所以默认行为确实是这样的。

至于你问的能不能指定特定客户端端口,答案是肯定的!虽然这个需求不算常见,但在一些特殊场景(比如防火墙强制要求客户端从特定端口发起请求、网络调试需要固定源端口)下完全合理,下面我给你两种可行的实现方法:

方法一:自定义HTTP适配器(通用方案)

requests本身没有直接暴露指定源端口的参数,但它基于urllib3实现,我们可以通过自定义适配器来修改urllib3的连接池配置,从而指定源端口:

import requests
from urllib3.poolmanager import PoolManager

class SourcePortAdapter(requests.adapters.HTTPAdapter):
    def __init__(self, source_port, *args, **kwargs):
        self.source_port = source_port
        super().__init__(*args, **kwargs)

    def init_poolmanager(self, connections, maxsize, block=False):
        # 初始化连接池时,通过source_address指定源端口
        self.poolmanager = PoolManager(
            num_pools=connections,
            maxsize=maxsize,
            block=block,
            source_address=('', self.source_port)  # 空字符串表示自动选择本地IP,端口为指定值
        )

# 使用示例
if __name__ == "__main__":
    # 创建会话并挂载自定义适配器
    session = requests.Session()
    target_port = 12345  # 你想要使用的客户端端口
    adapter = SourcePortAdapter(target_port)
    session.mount('http://', adapter)
    session.mount('https://', adapter)

    # 发起GET请求,此时会使用指定的12345端口作为源端口
    response = session.get('https://example.com')
    print(f"请求状态码: {response.status_code}")

代码说明:

  • 我们继承了requests的HTTPAdapter,重写了init_poolmanager方法,在创建PoolManager时传入source_address参数
  • source_address的格式是(本地IP, 端口),空字符串表示让系统自动选择合适的本地IP,你也可以指定具体的网卡IP(比如('192.168.1.5', 12345))
  • 将适配器挂载到session后,所有通过该session发起的请求都会使用指定的源端口

方法二:手动绑定socket(灵活定制方案)

如果需要更精细的控制(比如绑定到特定网卡+端口),可以手动创建socket并绑定端口,再让requests使用这个socket:

import requests
from socket import socket, AF_INET, SOCK_STREAM

# 创建socket并绑定到指定的本地IP和端口
local_ip = '192.168.1.5'  # 你的网卡IP
local_port = 12345  # 指定的客户端端口
s = socket(AF_INET, SOCK_STREAM)
s.bind((local_ip, local_port))

# 提前连接到目标服务器(以HTTPS为例,端口443)
s.connect(('example.com', 443))

# 自定义适配器,让请求使用我们绑定好的socket
class CustomSocketAdapter(requests.adapters.HTTPAdapter):
    def send(self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None):
        # 将请求的连接替换为我们已绑定的socket
        conn = self.poolmanager.connection_from_host('example.com', port=443)
        conn.sock = s
        request.connection = conn
        return super().send(request, stream, timeout, verify, cert, proxies)

# 使用示例
session = requests.Session()
adapter = CustomSocketAdapter()
session.mount('https://example.com', adapter)

response = session.get('https://example.com')
print(f"请求状态码: {response.status_code}")

注意事项:

  1. 端口可用性:确保指定的端口没有被其他进程占用,否则会抛出OSError: [Errno 98] Address already in use错误
  2. 端口范围:普通用户只能使用1024-65535之间的端口,1-1023是系统保留端口,需要root/管理员权限才能使用
  3. HTTPS兼容性:两种方法都支持HTTPS请求,因为urllib3会自动处理TLS握手,我们只是修改了底层socket的源端口

内容的提问来源于stack exchange,提问作者Jamboree

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:45:35