|
@@ -7,11 +7,12 @@ from . import db
|
|
|
class SearchDomain(object):
|
|
class SearchDomain(object):
|
|
|
"""search avaliable domain and save result"""
|
|
"""search avaliable domain and save result"""
|
|
|
|
|
|
|
|
- def __init__(self, params: dict, debug=False, export_all=True):
|
|
|
|
|
|
|
+ def __init__(self, params: dict, debug=False, export_all=True, log_callback=None):
|
|
|
'''
|
|
'''
|
|
|
初始化
|
|
初始化
|
|
|
debug 调试模式
|
|
debug 调试模式
|
|
|
export_all 是否导出所有域名,默认导出可用域名
|
|
export_all 是否导出所有域名,默认导出可用域名
|
|
|
|
|
+ log_callback 日志回调函数,用于GUI模式下显示日志
|
|
|
return:
|
|
return:
|
|
|
'''
|
|
'''
|
|
|
super(SearchDomain, self).__init__()
|
|
super(SearchDomain, self).__init__()
|
|
@@ -19,8 +20,40 @@ class SearchDomain(object):
|
|
|
self.export_all=export_all
|
|
self.export_all=export_all
|
|
|
self.input=params["input"]
|
|
self.input=params["input"]
|
|
|
self.output=params["output"]
|
|
self.output=params["output"]
|
|
|
- if debug == True:
|
|
|
|
|
- logging.basicConfig(level=logging.DEBUG)
|
|
|
|
|
|
|
+ self.log_callback = log_callback
|
|
|
|
|
+ self._output_file_checked = False # 标记输出文件是否已检查
|
|
|
|
|
+
|
|
|
|
|
+ # 获取当前模块的日志记录器
|
|
|
|
|
+ self.logger = logging.getLogger(__name__)
|
|
|
|
|
+
|
|
|
|
|
+ # 配置日志系统
|
|
|
|
|
+ if log_callback:
|
|
|
|
|
+ # 如果有日志回调函数,创建自定义处理器
|
|
|
|
|
+ # 创建自定义处理器,将日志输出到回调函数
|
|
|
|
|
+ class CallbackHandler(logging.Handler):
|
|
|
|
|
+ def __init__(self, callback):
|
|
|
|
|
+ super().__init__()
|
|
|
|
|
+ self.callback = callback
|
|
|
|
|
+
|
|
|
|
|
+ def emit(self, record):
|
|
|
|
|
+ msg = self.format(record)
|
|
|
|
|
+ if self.callback:
|
|
|
|
|
+ self.callback(msg)
|
|
|
|
|
+
|
|
|
|
|
+ self.logger.setLevel(logging.INFO)
|
|
|
|
|
+
|
|
|
|
|
+ # 检查是否已经添加了回调处理器,避免重复添加
|
|
|
|
|
+ has_callback_handler = any(isinstance(h, CallbackHandler) for h in self.logger.handlers)
|
|
|
|
|
+ if not has_callback_handler:
|
|
|
|
|
+ callback_handler = CallbackHandler(log_callback)
|
|
|
|
|
+ callback_handler.setLevel(logging.INFO)
|
|
|
|
|
+ formatter = logging.Formatter('%(message)s')
|
|
|
|
|
+ callback_handler.setFormatter(formatter)
|
|
|
|
|
+ self.logger.addHandler(callback_handler)
|
|
|
|
|
+ elif debug == True:
|
|
|
|
|
+ logging.basicConfig(level=logging.DEBUG, format='%(message)s', force=True)
|
|
|
|
|
+ else:
|
|
|
|
|
+ logging.basicConfig(level=logging.INFO, format='%(message)s', force=True)
|
|
|
|
|
|
|
|
def crawl(self, domain: str, index:int) -> None:
|
|
def crawl(self, domain: str, index:int) -> None:
|
|
|
'''
|
|
'''
|
|
@@ -31,16 +64,16 @@ class SearchDomain(object):
|
|
|
try:
|
|
try:
|
|
|
whi = whois.whois(domain)
|
|
whi = whois.whois(domain)
|
|
|
res = False
|
|
res = False
|
|
|
- logging.info(str(index) + ": searching domain:"+ domain + " is unavaliable.")
|
|
|
|
|
|
|
+ self.logger.info(str(index) + ": searching domain:"+ domain + " is unavaliable.")
|
|
|
except Exception as e:
|
|
except Exception as e:
|
|
|
error_str = str(e)
|
|
error_str = str(e)
|
|
|
# 检查是否是域名未注册的错误
|
|
# 检查是否是域名未注册的错误
|
|
|
if "No match" in error_str or "No match for" in error_str:
|
|
if "No match" in error_str or "No match for" in error_str:
|
|
|
res = True
|
|
res = True
|
|
|
- logging.info(str(index) + ": searching domain:"+ domain +" is avaliable.")
|
|
|
|
|
|
|
+ self.logger.info(str(index) + ": searching domain:"+ domain +" is avaliable.")
|
|
|
else:
|
|
else:
|
|
|
res = False
|
|
res = False
|
|
|
- logging.error(f"Error checking {domain}: {error_str}")
|
|
|
|
|
|
|
+ self.logger.error(f"Error checking {domain}: {error_str}")
|
|
|
if self.export_all:
|
|
if self.export_all:
|
|
|
self.saveRes(domain, res)
|
|
self.saveRes(domain, res)
|
|
|
else:
|
|
else:
|
|
@@ -51,6 +84,18 @@ class SearchDomain(object):
|
|
|
""" save result to file """
|
|
""" save result to file """
|
|
|
# db.Mysql().save()
|
|
# db.Mysql().save()
|
|
|
output_path = os.path.join(self.params["app_path"], self.output)
|
|
output_path = os.path.join(self.params["app_path"], self.output)
|
|
|
|
|
+ # 检查输出文件是否存在,不存在则创建并警告(只检查一次)
|
|
|
|
|
+ if not self._output_file_checked:
|
|
|
|
|
+ if not os.path.exists(output_path):
|
|
|
|
|
+ # 确保目录存在
|
|
|
|
|
+ dir_path = os.path.dirname(output_path)
|
|
|
|
|
+ if dir_path and not os.path.exists(dir_path):
|
|
|
|
|
+ os.makedirs(dir_path, exist_ok=True)
|
|
|
|
|
+ # 创建文件
|
|
|
|
|
+ with open(output_path, 'w', encoding='utf-8') as f:
|
|
|
|
|
+ pass
|
|
|
|
|
+ self.logger.warning(f"警告:输出文件不存在,已创建: {output_path}")
|
|
|
|
|
+ self._output_file_checked = True
|
|
|
db.File().save(output_path, domain + " " + str(res))
|
|
db.File().save(output_path, domain + " " + str(res))
|
|
|
|
|
|
|
|
def run(self):
|
|
def run(self):
|