告诉 urllib2 使用自定义 DNS

2024-04-06

我想告诉urllib2.urlopen (or a 定制开瓶器)使用127.0.0.1 (or ::1)来解析地址。我不会改变我的/etc/resolv.conf, 然而。

一种可能的解决方案是使用类似的工具dnspython查询地址和httplib构建自定义 url 打开器。我更愿意告诉urlopen不过要使用自定义名称服务器。有什么建议么?


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

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

不过,一旦设置了“Host:”标头,您就可以解析主机并将 IP 地址传递给 opener。

我建议你子类化httplib.HTTPConnection,并包裹connect修改方法self.host在将其传递给之前socket.create_connection.

然后子类化HTTPHandler (and HTTPSHandler)来替换http_open方法与通过你的HTTPConnection而不是 httplib 自己的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...

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

告诉 urllib2 使用自定义 DNS 的相关文章