Python中当系统DNS不可用时如何指定DNS服务器或实现类似Hosts的方法?
简单点说,我想用 Google 的 DNS Over Https 。
但这里有一个问题,如果我只是作为一个候选的 DNS 服务来启动是没问题的,但如果要作为本机唯一的 DNS 服务器,这就有个鸡生蛋蛋生鸡的问题了:
我需要访问 dns.google.com 才能解析数据,可是我不知道 dns.google.com 的 IP 地址,于是我向自己查询,然后死循环。
所以,有没有什么办法可以给 python 程序指定一个 DNS 解析器用于一些必要的基本解析呢,例如用 114DNS 先完成必要的域名解析。
或者有没有类似写 Hosts 的方法,直接告诉 python 这些域名的地址,具体的来说,是告诉 urllib 和 aiohttp 域名的 A 地址,这样就不需要额外的 DNS 来解析 dns.google.com 了。
Python中当系统DNS不可用时如何指定DNS服务器或实现类似Hosts的方法?
request 的时候直接用 IP 替代 dns.google.com ,然后加上一个 HOST: dns.google.com 的 header ?
遇到系统DNS不可用时,可以绕过系统设置直接指定DNS服务器。这里提供两种实用方法:
方法一:使用dnspython库指定DNS服务器
import dns.resolver
def query_with_custom_dns(domain, dns_server='8.8.8.8'):
"""使用指定DNS服务器查询域名"""
resolver = dns.resolver.Resolver()
resolver.nameservers = [dns_server] # 设置自定义DNS服务器
try:
answers = resolver.resolve(domain, 'A')
return [answer.to_text() for answer in answers]
except dns.resolver.NXDOMAIN:
return "域名不存在"
except Exception as e:
return f"查询失败: {str(e)}"
# 使用示例
print(query_with_custom_dns('baidu.com', '114.114.114.114'))
方法二:实现类似Hosts的本地解析
import socket
class LocalDNSResolver:
def __init__(self):
self.hosts_map = {
'example.com': '93.184.216.34',
'localhost': '127.0.0.1',
# 添加更多映射
}
def resolve(self, hostname):
"""优先使用本地映射,失败则回退到系统DNS"""
if hostname in self.hosts_map:
return self.hosts_map[hostname]
try:
# 尝试系统解析(如果可用)
return socket.gethostbyname(hostname)
except socket.gaierror:
raise ValueError(f"无法解析主机名: {hostname}")
# 使用示例
resolver = LocalDNSResolver()
print(resolver.resolve('example.com')) # 返回本地映射
print(resolver.resolve('google.com')) # 回退到系统DNS
关键点说明:
dnspython方法完全绕过系统DNS设置,直接与指定服务器通信- 本地解析器优先使用内存中的映射表,适合需要覆盖特定域名的情况
- 两种方法可以结合使用,先查本地映射,再查备用DNS服务器
简单总结:用dnspython指定DNS或自己实现一个本地解析器。
先用 dnspython 去查 ip ,然后给 urllib 设置 Host 头,用 IP 去请求就好了
dnspod 家的 httpdns 貌似可以解决
ssl 握手包里有域名,这样确实不行
自定义一个 connector 应该可以 http://aiohttp.readthedocs.io/en/stable/_modules/aiohttp/connector.html
不过正确的实现应该像五楼说的那样。
我希望的就是这个东西能够完全独立于其他的服务,只依赖基本的网络连接。
不可能的,基本网络连接也需要初始 DNS 的
别扯,我已经搞定了。
好吧,我错了,好像还是有问题。
哈哈哈,是我代码写错了,还是可以的。
基本的网络连接怎么定义???
楼主搞定了没有??
有 TCP 和 UDP 连接就行啊
append 的部分就是可用的代码啊


