python使用requests库解析IPv6地址

无人久伴 提交于 2020-01-20 03:28:59

python使用requests库解析IPv6地址

请求一个网页时,如果需要DNS解析IPv6地址,requests好像并不支持切换IPv6,通过分析requests源码,requests使用了urllib3来处理连接:
urllib3.connection.HTTPConnection

    def _new_conn(self):
        """ Establish a socket connection and set nodelay settings on it.

        :return: New socket connection.
        """
        extra_kw = {}
        if self.source_address:
            extra_kw['source_address'] = self.source_address

        if self.socket_options:
            extra_kw['socket_options'] = self.socket_options

        try:
            conn = connection.create_connection(
                (self._dns_host, self.port), self.timeout, **extra_kw)

        except SocketTimeout as e:
            raise ConnectTimeoutError(
                self, "Connection to %s timed out. (connect timeout=%s)" %
                (self.host, self.timeout))

        except SocketError as e:
            raise NewConnectionError(
                self, "Failed to establish a new connection: %s" % e)

        return conn

深入到connection.create_connection发现是通过allowed_gai_family方法获取地址族:

def create_connection(address, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
                      source_address=None, socket_options=None):
   .
   .
   .
   
    family = allowed_gai_family()

    for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):
        af, socktype, proto, canonname, sa = res
   .
   .
   .

所以我们只需要重写allowed_gai_family方法切换地址族为AF_INET6就可以了,这里给出猴子补丁:

USE_IPV6 = True

def allowed_gai_family():
    family = socket.AF_INET
    if USE_IPV6:
        family = socket.AF_INET6
    return family

urllib3.util.connection.allowed_gai_family = allowed_gai_family
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!