杰瑞科技汇

python gethostbyaddr

Of course! In Python, the standard library function for getting the hostname from an IP address is socket.gethostbyaddr().

python gethostbyaddr-图1
(图片来源网络,侵删)

Here's a detailed breakdown of how to use it, including examples, error handling, and important caveats.

The Core Function: socket.gethostbyaddr(ip_address)

This function performs a reverse DNS lookup. It queries the DNS for the Pointer (PTR) record associated with the given IP address.

Return Value

If successful, it returns a tuple with three elements:

  1. hostname (string): The primary canonical hostname. For example, 'google.com'.
  2. aliaslist (list of strings): A list of alternative hostnames (CNAME records) for the same address. This list can be empty.
  3. ipaddrlist (list of strings): A list of IP addresses for the same interface (often just the one you looked up). This list can also be empty.

Example 1: Successful Lookup

Let's look up a well-known public IP address, like Google's DNS server (8.8.8).

python gethostbyaddr-图2
(图片来源网络,侵删)
import socket
ip_address = '8.8.8.8'
try:
    hostname, aliaslist, ipaddrlist = socket.gethostbyaddr(ip_address)
    print(f"IP Address: {ip_address}")
    print(f"Hostname: {hostname}")
    print(f"Aliases: {aliaslist}")
    print(f"IP Addresses: {ipaddrlist}")
except socket.herror as e:
    # herror is for hostname lookup errors
    print(f"Could not resolve hostname for {ip_address}: {e}")
except Exception as e:
    # Catch any other unexpected errors
    print(f"An unexpected error occurred: {e}")

Expected Output:

IP Address: 8.8.8.8
Hostname: dns.google
Aliases: []
IP Addresses: ['8.8.8.8']

Example 2: Handling Common Errors (No Reverse DNS)

Many IP addresses, especially those from residential or mobile ISPs, do not have a reverse DNS entry. If you try to look one up, socket.gethostbyaddr() will raise a socket.herror exception.

It's crucial to wrap the call in a try...except block.

import socket
# This is a common example of an IP with no reverse DNS entry
ip_address = '93.184.216.34' # This is the IP for example.com, but often has no rDNS
try:
    hostname, aliaslist, ipaddrlist = socket.gethostbyaddr(ip_address)
    print(f"Success! Hostname for {ip_address} is {hostname}")
except socket.herror as e:
    # This is the expected exception when no hostname is found
    print(f"Lookup failed for {ip_address}: {e}")
    print("This is a common and normal result.")
except Exception as e:
    print(f"An unexpected error occurred: {e}")

Expected Output:

python gethostbyaddr-图3
(图片来源网络,侵删)
Lookup failed for 93.184.216.34: [Errno 1] Unknown host
This is a common and normal result.

Example 3: Localhost

This is a reliable example that works on any machine.

import socket
ip_address = '127.0.0.1' # The standard loopback address
try:
    hostname, aliaslist, ipaddrlist = socket.gethostbyaddr(ip_address)
    print(f"IP Address: {ip_address}")
    print(f"Hostname: {hostname}") # Usually 'localhost'
    print(f"Aliases: {aliaslist}")
    print(f"IP Addresses: {ipaddrlist}")
except socket.herror as e:
    print(f"Could not resolve hostname for {ip_address}: {e}")

Expected Output:

IP Address: 127.0.0.1
Hostname: localhost
Aliases: []
IP Addresses: ['127.0.0.1']

Example 4: Looking Up Your Own Machine's IP

You can get your local machine's IP address and then look it up.

import socket
# Get the local machine's IP address
# This gets the IP of the default route to the internet
try:
    # Connect to a remote server to determine the local IP
    # This is a common trick to find the outgoing IP
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.connect(("8.8.8.8", 80))
    local_ip = s.getsockname()[0]
    s.close()
    print(f"Found local IP: {local_ip}")
    # Now perform the reverse lookup
    hostname, aliaslist, ipaddrlist = socket.gethostbyaddr(local_ip)
    print("\n--- Reverse Lookup Results ---")
    print(f"Hostname: {hostname}")
    print(f"Aliases: {aliaslist}")
    print(f"IP Addresses: {ipaddrlist}")
except socket.herror as e:
    print(f"\nCould not resolve hostname for {local_ip}: {e}")
except Exception as e:
    print(f"\nAn error occurred: {e}")

Key Considerations and Best Practices

  1. Always Handle Exceptions: As shown in the examples, socket.herror is the most common exception you'll encounter. Never call gethostbyaddr() without a try...except block in production code.

  2. Timeouts: By default, this function can block for a while if the DNS server is unresponsive. It's good practice to set a timeout on the socket before calling it.

    import socket
    import time
    ip_address = '1.1.1.1' # Cloudflare's DNS
    # Create a default timeout context
    # This will apply to all socket operations in this block
    original_timeout = socket.getdefaulttimeout()
    socket.setdefaulttimeout(2.0) # Set a 2-second timeout
    try:
        start_time = time.time()
        hostname, aliaslist, ipaddrlist = socket.gethostbyaddr(ip_address)
        end_time = time.time()
        print(f"Lookup successful in {end_time - start_time:.2f} seconds.")
        print(f"Hostname: {hostname}")
    except socket.herror as e:
        print(f"Lookup failed: {e}")
    except socket.timeout:
        print("Lookup timed out after 2 seconds.")
    finally:
        # Always restore the original timeout
        socket.setdefaulttimeout(original_timeout)
  3. What is "Canonical Hostname"? The first element returned is the "canonical" name. This is the official, primary hostname for that IP, as defined by the DNS administrator. It might not be the most "human-friendly" name, but it's the one that should be used for consistency.

  4. Firewalls and Security: Some networks or firewalls may block reverse DNS queries, causing the lookup to fail even if a record exists. The function will raise a socket.timeout or socket.herror in this case.

Summary: gethostbyaddr vs. gethostbyname

It's easy to confuse these two functions.

Function Purpose Example
socket.gethostbyname(hostname) Forward Lookup: Converts a hostname (like google.com) to an IP address (like 250.191.78). gethostbyname('google.com')
socket.gethostbyaddr(ip_address) Reverse Lookup: Converts an IP address (like 8.8.8) to a hostname (like dns.google). gethostbyaddr('8.8.8.8')
分享:
扫描分享到社交APP
上一篇
下一篇