代码之家  ›  专栏  ›  技术社区  ›  Attila O.

告诉urllib2使用自定义DNS

  •  14
  • Attila O.  · 技术社区  · 16 年前

    我想告诉你 urllib2.urlopen 定制开瓶器 127.0.0.1 ::1 )解析地址。我不会改变我的想法 /etc/resolv.conf

    一个可能的解决方案是使用类似 dnspython httplib urlopen 使用自定义名称服务器。有什么建议吗?

    3 回复  |  直到 16 年前
        1
  •  23
  •   MattH    16 年前

    看起来名称解析最终由 socket.create_connection

    -> urllib2.urlopen
    -> httplib.HTTPConnection
    -> socket.create_connection
    

    虽然一旦设置了“Host:”头,您就可以解析主机并将IP地址向下传递到开场白。

    我建议你把 httplib.HTTPConnection connect 修改方法 self.host 在交给 .

    然后子类 HTTPHandler (及 HTTPSHandler )取代 http_open 方法与通过 HTTPConnection do_open .

    import urllib2
    import httplib
    import socket
    
    def MyResolver(host):
      if host == 'news.bbc.co.uk':
        return '66.102.9.104' # Google IP
      else:
        return host
    
    class MyHTTPConnection(httplib.HTTPConnection):
      def connect(self):
        self.sock = socket.create_connection((MyResolver(self.host),self.port),self.timeout)
    class MyHTTPSConnection(httplib.HTTPSConnection):
      def connect(self):
        sock = socket.create_connection((MyResolver(self.host), self.port), self.timeout)
        self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file)
    
    class MyHTTPHandler(urllib2.HTTPHandler):
      def http_open(self,req):
        return self.do_open(MyHTTPConnection,req)
    
    class MyHTTPSHandler(urllib2.HTTPSHandler):
      def https_open(self,req):
        return self.do_open(MyHTTPSConnection,req)
    
    opener = urllib2.build_opener(MyHTTPHandler,MyHTTPSHandler)
    urllib2.install_opener(opener)
    
    f = urllib2.urlopen('http://news.bbc.co.uk')
    data = f.read()
    from lxml import etree
    doc = etree.HTML(data)
    
    >>> print doc.xpath('//title/text()')
    ['Google']
    

    显然,如果您使用HTTPS,会出现证书问题,您需要填写MyResolver。。。

        2
  •  22
  •   Taha Jahangir    13 年前

    socket.getaddrinfo .

    例如,此代码为dns查找添加(无限制)缓存。

    import socket
    prv_getaddrinfo = socket.getaddrinfo
    dns_cache = {}  # or a weakref.WeakValueDictionary()
    def new_getaddrinfo(*args):
        try:
            return dns_cache[args]
        except KeyError:
            res = prv_getaddrinfo(*args)
            dns_cache[args] = res
            return res
    socket.getaddrinfo = new_getaddrinfo
    
        3
  •  0
  •   speakman    16 年前