【Python】request绑定指定IP

实现source适配器

#!/usr/bin/env python
# coding=utf-8
# (C) Copyright 2019-2019, sangfor.Co.Ltd. All rights reserved.

"""
requests_toolbelt.source_adapter
================================
This file contains an implementation of the SourceAddressAdapter originally
demonstrated on the Requests GitHub page.
"""
from requests.adapters import HTTPAdapter
from requests.packages.urllib3 import poolmanager


class SourceAddressAdapter(HTTPAdapter):
    """
    A Source Address Adapter for Python Requests that enables you to choose the
    local address to bind to. This allows you to send your HTTP requests from a
    specific interface and IP address.
    Two address formats are accepted. The first is a string: this will set the
    local IP address to the address given in the string, and will also choose a
    semi-random high port for the local port number.
    The second is a two-tuple of the form (ip address, port): for example,
    ``('10.10.10.10', 8999)``. This will set the local IP address to the first
    element, and the local port to the second element. If ``0`` is used as the
    port number, a semi-random high port will be selected.
    .. warning:: Setting an explicit local port can have negative interactions
                 with connection-pooling in Requests: in particular, it risks
                 the possibility of getting "Address in use" errors. The
                 string-only argument is generally preferred to the tuple-form.
    Example usage:
    .. code-block:: python
        import requests
        from requests_toolbelt.adapters.source import SourceAddressAdapter
        s = requests.Session()
        s.mount('http://', SourceAddressAdapter('10.10.10.10'))
        s.mount('https://', SourceAddressAdapter(('10.10.10.10', 8999)))
    """
    def __init__(self, source_address, **kwargs):
        if isinstance(source_address, (str, bytes)):
            self.source_address = (source_address, 0)
        elif isinstance(source_address, tuple):
            self.source_address = source_address
        else:
            raise TypeError(
                "source_address must be IP address string or (ip, port) tuple"
            )

        super(SourceAddressAdapter, self).__init__(**kwargs)

    def init_poolmanager(self, connections, maxsize, block=False):
        self.poolmanager = poolmanager.PoolManager(
            num_pools=connections,
            maxsize=maxsize,
            block=block,
            source_address=self.source_address)

    def proxy_manager_for(self, *args, **kwargs):
        kwargs['source_address'] = self.source_address
        return super(SourceAddressAdapter, self).proxy_manager_for(
            *args, **kwargs)


调用如下

    def to_src_ip_requests_get(self, source_ips, url, data=None, headers=None, timeout=None):
        """
        指定源IP发起请求,直到获取成功的响应值
        :param source_ips:
        :param url:
        :param data:
        :param headers:
        :param timeout:
        :return:
        """
        if not isinstance(source_ips, list):
            return False

        if timeout is None:
            timeout = self.timeout
        if headers is None:
            headers = self.headers
        if data is None:
            data = {}

        s = requests.Session()
        for source_ip in source_ips:
            try:
                new_source = source.SourceAddressAdapter(source_ip)
                s.mount('http://', new_source)
                s.mount('https://', new_source)
                response = s.get(url=url, headers=headers, data=json.dumps(data), timeout=timeout,
                                 verify=False)

                if response.json().get("success"):
                    return response.json()
            except Exception as error:
                logging.warning(error)
        return False

安装psutil

pip install psutil

获取本机所有IPV4

def get_local_ips(sta_ip):
    """
    获取本机所有IPV4地址
    :return:
    """
    error_ips = []
    ips = list()
    for nic, addresses in psutil.net_if_addrs().iteritems():
        if nic == 'lo':
            continue

        ip_type = socket.AF_INET if ":" not in sta_ip else socket.AF_INET6
        for a in addresses:
            if a.family == ip_type and a.address not in error_ips:
                ips.append(a.address)
    return ips

你可能感兴趣的:(Python)