有时候排查域名解析问题时,我们需要反复在终端和网页 DNS 工具之间切换,效率很低。今天用 OpenCode 写一个命令行 DNS 记录批量查询工具,支持 A、AAAA、MX、CNAME、TXT 等多种记录类型,还能批量查询多个域名,输出 JSON 格式方便集成到脚本中。
确保本地安装了 Python 3.8+ 和 OpenCode。新建项目目录后,只需一个命令启动:
pip install dnspython
然后在终端打开项目目录,直接用自然语言跟 OpenCode 对话即可。
我对 OpenCode 说:
> 帮我用 Python 写一个命令行 DNS 查询工具,接收域名参数,查询 A 记录并打印结果。使用 dnspython 库。
OpenCode 立即生成了初版脚本,导入了 dns.resolver,用 argparse 处理命令行参数,核心查询逻辑不到 20 行。
import argparse
import dns.resolver
def main():
parser = argparse.ArgumentParser()
parser.add_argument("domain")
args = parser.parse_args()
answers = dns.resolver.resolve(args.domain, "A")
for a in answers:
print(a.to_text())
if __name__ == "__main__":
main()
关键要点:OpenCode 对标准库非常熟悉,argparse 和异常处理的用法都是惯用的 Python 写法。
一个 DNS 查询工具不能只查 A 记录。我继续追加需求:
我对 OpenCode 说:
> 加一个 -t 参数支持指定记录类型,比如 A、AAAA、MX、CNAME、TXT、NS。再添加 --all 参数一键查询所有常见类型。
OpenCode 更新了代码,定
义了 RECORD_TYPES 列表,将 resolve() 的第二个参数改为动态传入,同时在 argparse 中新增了 --type 和 --all 两个参数。这是典型的"增量迭代"——每加一个功能只需一句话。
单域名查询还不够,排查问题时经常需要对比多个域名。
我对 OpenCode 说:
> 支持一次传多个域名,比如 python dns.py baidu.com google.com。再加一个 --json 参数,输出 JSON 格式的结果。
OpenCode 将 domains 改为 nargs="+" 接收多个参数,新增了 query_domain() 函数统一处理每个域名的查询,返回结构化字典。JSON 输出直接用 json.dumps 一行搞定,TTL 信息也顺手带上了。
results = [query_domain(d, types, args.nameserver) for d in args.domains]
if args.json:
print(json.dumps(results, ensure_ascii=False, indent=2))
关键要点:OpenCode 善于把握"最小改动原则"——它不会重写整个文件,而是在现有代码基础上精准修改。这点在多人协作或维护老项目时非常重要。
最后一步是提升健壮性——超时、域名不存在、网络异常都要有中文提示。
我对 OpenCode 说:
> 加上超时处理和错误提示,域名不存在时提示"域名不存在",超时时提示"查询超时"。美化一下输出格式,加上分隔线和 TTL 显示。
OpenCode 给 Resolver 设置了 5 秒超时,用 try/except 分别捕获 NXDOMAIN、Timeout 等异常,输出带颜色的分隔线。还贴心地添加了 epilog 示例帮助,用户执行 python dns.py -h 就能看到用法。
整个过程四轮对话、四分钟完成,无需手写一行代码。
#!/usr/bin/env python3
import argparse
import json
import dns.resolver
RECORD_TYPES = ["A", "AAAA", "MX", "CNAME", "TXT", "NS", "SOA", "CAA"]
def resolve_dns(domain: str, record_type: str, nameserver: str = None):
resolver = dns.resolver.Resolver()
resolver.timeout = 5
resolver.lifetime = 5
if nameserver:
resolver.nameservers = [nameserver]
answers = resolver.resolve(domain, record_type)
return [{"value": str(a).replace('"', ''), "ttl": answers.rrset.ttl} for a in answers]
def query_domain(domain: str, types: list, nameserver: str = None):
result = {"domain": domain, "records": {}}
for rt in types:
try:
result["records"][rt] = resolve_dns(domain, rt, nameserver)
except dns.resolver.NoAnswer:
result["records"][rt] = []
except dns.resolver.NXDOMAIN:
result["records"][rt] = [{"value": f"域名 {domain} 不存在", "ttl": 0}]
except dns.resolver.Timeout:
result["records"][rt] = [{"value": "查询超时", "ttl": 0}]
except Exception as e:
result["records"][rt] = [{"value": f"查询失败: {e}", "ttl": 0}]
return result
def display_result(result: dict):
print(f"\n{'='*60}")
print(f"域名: {result['domain']}")
print(f"{'='*60}")
for rt, records in result["records"].items():
print(f"\n[{rt} 记录]")
if not records:
print(" (无记录)")
continue
for r in records:
ttl = f" [TTL: {r['ttl']}s]" if r['ttl'] > 0 else ""
print(f" → {r['value']}{ttl}")
def main():
parser = argparse.ArgumentParser(
description="DNS 记录查询工具 — 命令行版 dig",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
示例:
%(prog)s baidu.com
%(prog)s baidu.com -t MX
%(prog)s baidu.com --all -n 8.8.8.8
%(prog)s baidu.com google.com --json
"""
)
parser.add_argument("domains", nargs="+", help="要查询的域名(支持多个)")
parser.add_argument("-t", "--type", default="A", help="记录类型 (默认: A)")
parser.add_argument("-n", "--nameserver", help="指定 DNS 服务器")
parser.add_argument("-a", "--all", action="store_true", help="查询所有常见记录")
parser.add_argument("--json", action="store_true", help="JSON 格式输出")
args = parser.parse_args()
types = RECORD_TYPES if args.all else [args.type.upper()]
results = [query_domain(d, types, args.nameserver) for d in args.domains]
if args.json:
print(json.dumps(results, ensure_ascii=False, indent=2))
else:
for r in results:
display_result(r)
print()
if __name__ == "__main__":
main()
运行示例:
$ python dns.py baidu.com -t A ============================================================ 域名: baidu.com ============================================================ [A 记录] → 110.242.68.66 [TTL: 600s] → 39.156.66.10 [TTL: 600s]
用 OpenCode 开发这个小工具的感受可以概括为三个字:说就行。
不用查 dns.resolver 的 API 文档,不用翻 argparse 的 nargs 怎么用,也不用纠结 argparse 的排版格式——直接告诉 OpenCode 你要什么,它生成代码,你验证结果。四轮对话下来,一个功能完善、带容错、支持 JSON 输出的 DNS 查询工具就完成了。
传统方式你可能需要花 20 分钟查文档、调参数、处理边界情况;用 OpenCode 只需要 4 分钟,你把精力放在"想清楚需求"上,而不是"记住 API"上。这就是 AI 编程助手带来的效率跃迁。