杰瑞科技汇

Python dns.resolver如何正确使用?

Of course! The dns.resolver module is a powerful and popular part of the dnspython library, which is the de-facto standard for DNS operations in Python. It allows you to programmatically perform DNS queries, just like a command-line tool like dig or nslookup.

Python dns.resolver如何正确使用?-图1
(图片来源网络,侵删)

Here’s a comprehensive guide covering everything from installation to advanced usage.

Installation

First, you need to install the dnspython library. You can do this easily using pip:

pip install dnspython

Basic Usage: Resolving a DNS Record

The most common task is to resolve a domain name to an IP address (an A record). The process involves creating a Resolver object, querying it, and then iterating through the results.

Here's a simple example to get the A records for google.com:

Python dns.resolver如何正确使用?-图2
(图片来源网络,侵删)
import dns.resolver
def resolve_domain(domain):
    """
    Resolves a domain name to its A records (IPv4 addresses).
    """
    try:
        # Create a resolver object
        resolver = dns.resolver.Resolver()
        # Set a custom nameserver (optional, defaults to system's)
        # resolver.nameservers = ['8.8.8.8', '1.1.1.1']
        # Query for A records
        answers = resolver.resolve(domain, 'A')
        print(f"--- A records for {domain} ---")
        for rdata in answers:
            # rdata is a dns.rdatatype.A object
            # The address is stored in the 'address' attribute
            print(f"IP Address: {rdata.address}")
    except dns.resolver.NXDOMAIN:
        print(f"Error: The domain {domain} does not exist.")
    except dns.resolver.NoAnswer:
        print(f"Error: The domain {domain} does not have an A record.")
    except dns.resolver.Timeout:
        print(f"Error: No response from the DNS server for {domain}.")
    except Exception as e:
        print(f"An unexpected error occurred: {e}")
# --- Example Usage ---
resolve_domain('google.com')
resolve_domain('this-domain-does-not-exist-12345.com') # Will trigger NXDOMAIN

Output:

--- A records for google.com ---
IP Address: 142.250.217.78
IP Address: 142.250.217.101
IP Address: 142.250.217.139
IP Address: 142.250.217.113
IP Address: 142.250.217.125
IP Address: 142.250.217.147
...

Handling Different Record Types

The dns.resolver.resolve() function is versatile. You can query for any valid DNS record type by changing the second argument.

Here are examples for common record types:

MX (Mail Exchange) Records

Shows mail servers responsible for receiving email on a domain.

Python dns.resolver如何正确使用?-图3
(图片来源网络,侵删)
import dns.resolver
try:
    answers = dns.resolver.resolve('google.com', 'MX')
    print(f"--- MX records for google.com ---")
    for rdata in answers:
        # rdata is a dns.rdatatype.MX object
        # It has 'preference' and 'exchange' attributes
        print(f"  Priority: {rdata.preference}, Mail Server: {rdata.exchange}")
except Exception as e:
    print(f"An error occurred: {e}")

Output:

--- MX records for google.com ---
  Priority: 10, Mail Server: aspmx.l.google.com
  Priority: 30, Mail Server: alt1.aspmx.l.google.com
  Priority: 20, Mail Server: alt2.aspmx.l.google.com
  Priority: 40, Mail Server: alt3.aspmx.l.google.com
  Priority: 5, Mail Server: alt4.aspmx.l.google.com

CNAME (Canonical Name) Records

Shows an alias for another domain name.

import dns.resolver
try:
    answers = dns.resolver.resolve('www.google.com', 'CNAME')
    print(f"--- CNAME records for www.google.com ---")
    for rdata in answers:
        # rdata is a dns.rdatatype.CNAME object
        # The target is stored in the 'target' attribute
        print(f"Alias for: {rdata.target}")
except Exception as e:
    print(f"An error occurred: {e}")

Output:

--- CNAME records for www.google.com ---
Alias for: www.google.com.

TXT (Text) Records

Stores arbitrary text strings, often used for SPF, DKIM, or verification.

import dns.resolver
try:
    answers = dns.resolver.resolve('google.com', 'TXT')
    print(f"--- TXT records for google.com ---")
    for rdata in answers:
        # rdata.strings is a list of bytes objects
        for txt_string in rdata.strings:
            print(f"  Text: {txt_string.decode('utf-8')}")
except Exception as e:
    print(f"An error occurred: {e}")

Output:

--- TXT records for google.com ---
  Text: v=spf1 include:_netblocks.google.com include:_netblocks2.google.com include:_netblocks3.google.com ~all
  Text: apple-site-verification=.....................
  Text: google-site-verification=.....................
  ...

NS (Name Server) Records

Shows the authoritative name servers for a domain.

import dns.resolver
try:
    answers = dns.resolver.resolve('google.com', 'NS')
    print(f"--- NS records for google.com ---")
    for rdata in answers:
        # rdata is a dns.rdatatype.NS object
        print(f"  Name Server: {rdata.target}")
except Exception as e:
    print(f"An error occurred: {e}")

Output:

--- NS records for google.com ---
  Name Server: ns3.google.com.
  Name Server: ns4.google.com.
  Name Server: ns1.google.com.
  Name Server: ns2.google.com.

Advanced Features

Changing Nameservers

By default, dnspython uses the nameservers listed in your system's /etc/resolv.conf (on Linux/macOS) or the Windows network settings. You can override this to use specific servers, like Google's Public DNS or Cloudflare's DNS.

import dns.resolver
# Use Google's Public DNS
resolver = dns.resolver.Resolver()
resolver.nameservers = ['8.8.8.8', '8.8.4.4']
try:
    answers = resolver.resolve('google.com', 'A')
    print(f"Resolved via Google's DNS:")
    for rdata in answers:
        print(f"  {rdata.address}")
except Exception as e:
    print(f"An error occurred: {e}")

Handling Timeouts and Retries

DNS queries can sometimes be slow or fail. You can configure the resolver to wait longer for a response and to retry a certain number of times.

import dns.resolver
resolver = dns.resolver.Resolver()
# Set timeout to 5 seconds (default is 3)
resolver.timeout = 5
# Set number of retries to 2 (default is 3)
resolver.retry_servfail = 2
try:
    answers = resolver.resolve('google.com', 'A')
    # ... process answers ...
except dns.resolver.Timeout:
    print("The query timed out.")
except Exception as e:
    print(f"An error occurred: {e}")

Reverse DNS Lookup (PTR Record)

A reverse lookup maps an IP address to a domain name.

import dns.resolver
def reverse_lookup(ip_address):
    try:
        # Use the resolve method with 'PTR' and the IP address
        # The IP address must be converted to a special format
        # e.g., 8.8.8.8 becomes 8.8.8.8.in-addr.arpa.
        answers = dns.resolver.resolve_address(ip_address)
        print(f"--- Reverse DNS for {ip_address} ---")
        for rdata in answers:
            # rdata is a dns.rdatatype.PTR object
            print(f"  Domain Name: {rdata.target}")
    except Exception as e:
        print(f"An error occurred: {e}")
reverse_lookup('8.8.8.8')

Output:

--- Reverse DNS for 8.8.8.8 ---
  Domain Name: dns.google.

Common Exceptions

Handling exceptions is crucial for writing robust DNS clients.

  • dns.resolver.NXDOMAIN: The domain name does not exist.
  • dns.resolver.NoAnswer: The name server does not have an answer for the query (e.g., an MX record for a domain that only has A records).
  • dns.resolver.Timeout: No name server responded within the configured timeout.
  • dns.resolver.NoNameservers: No non-broken nameservers are available to answer the query. This can indicate a network connectivity issue.
  • dns.exception.DNSException: The base class for all dnspython exceptions. You can catch this to handle any DNS-related error.
分享:
扫描分享到社交APP
上一篇
下一篇