Python socket.gethostbyname报[Errno -2] Name or service not known错误求解
域名批量解析失败问题解决方案
核心问题原因
- 你单独创建的socket超时配置未生效:
socket.gethostbyname方法使用全局默认socket配置,你单独实例化的s对象的超时设置不会对它生效 - 域名预处理缺失:如果读取的域名带
http://、https://前缀、多余空格、换行符、后缀斜杠,都会导致gethostbyname识别失败 - 循环内赋值逻辑错误:你写的
df['IPaddr'] = socket.gethostbyname(DN)是对整个DataFrame列赋值,应该在循环内逐行赋值 - 无查询间隔控制:批量高频查询会触发DNS服务器限流,导致正常域名也解析失败
修正方案
- 先对读取的域名列做预处理,去掉无效字符和前缀
- 替换
gethostbyname为支持自定义超时的解析实现,或者修改全局默认socket超时 - 循环内增加短延迟,避免触发限流
- 完善异常捕获的错误日志输出,方便定位单个域名的问题
修正后代码片段
import whois import matplotlib.pyplot as plt import numpy as np import pandas as pd import socket import os import csv import datetime import time import requests from ipwhois import IPWhois from urllib import request from ipwhois.utils import get_countries import tldextract from ipwhois.utils import get_countries countries = get_countries(is_legacy_xml=True) from ipwhois.experimental import bulk_lookup_rdap from ipwhois.hr import (HR_ASN, HR_ASN_ORIGIN, HR_RDAP_COMMON, HR_RDAP, HR_WHOIS, HR_WHOIS_NIR) countries = get_countries(is_legacy_xml=True) import ipaddress # 修改全局默认socket超时,对gethostbyname生效 socket.setdefaulttimeout(10) df = pd.read_csv('a.csv') # 新增域名预处理:去掉前后空格、去掉http/https前缀、去掉后缀斜杠 df['domain'] = df['domain'].str.strip().str.replace(r'^https?://', '', regex=True).str.rstrip('/') # 初始化IP列 df['IPaddr'] = '' #Date Processing Function def check_date_type(d): if type(d) is datetime.datetime: return d if type(d) is list: return d[0] for index,row in df.iterrows(): DN = row['domain'] try: ip = socket.gethostbyname(DN) df.loc[index, 'IPaddr'] = ip # 加0.2秒延迟,避免DNS限流 time.sleep(0.2) except socket.error as e: # 可以打印失败的域名方便排查 print(f"域名{DN}解析失败:{e}") df.loc[index, 'IPaddr'] = '解析失败'
如果调整后还是有大量解析失败,可以尝试修改本机的DNS服务器为公共DNS,比如谷歌的8.8.8.8、国内的114.114.114.114后再测试。
内容的提问来源于stack exchange,提问作者Loknath Basak
相关产品推荐
相关产品推荐

