Скажите urllib2 использовать пользовательский DNS

Я хотел бы сказать urllib2.urlopen (или пользовательский новичок) для использования 127.0.0.1 (или ::1) разрешить адреса. Я не изменил бы мой /etc/resolv.conf,как бы то ни было.

Одно возможное решение состоит в том, чтобы использовать инструмент как dnspython запрашивать адреса и httplib создавать пользовательского новичка URL. Я предпочел бы говорить urlopen использовать пользовательский сервер имен все же. Какие-либо предложения?

14
задан Attila O. 10 February 2010 в 11:46
поделиться

2 ответа

Похоже, что разрешение имен в конечном итоге обрабатывается socket.create_connection .

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

Хотя после того, как заголовок «Host:» был установлен, вы можете разрешить хост и передать IP-адрес открывателю.

Я бы посоветовал вам создать подкласс httplib.HTTPConnection и обернуть метод connect для изменения self.host перед его передачей в сокет . .create_connection .

Затем подкласс HTTPHandler 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 ...

21
ответ дан 1 December 2019 в 07:12
поделиться

Вам нужно будет реализовать свой собственный клиент поиска dns (или использовать dnspython, как вы сказали). Процедура поиска имен в glibc довольно сложна для обеспечения совместимости с другими системами имен без dns. Например, в библиотеке glibc вообще нет возможности указать конкретный DNS-сервер.

0
ответ дан 1 December 2019 в 07:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: