Siguiendo estos pasos aprenderás a programar una herramienta para limpiar y purgar tu base de datos de direcciones de correo electrónico peligrosas e indeseadas.
- Tiempo de implementación: 2 min
- Nivel de dificultad: Fácil
Detector de dominios peligrosos – Script en Python
El script en Python presentado tiene el propósito de extraer dominios de correos electrónicos desde un archivo (que puede estar en formato .xlsx
, .csv
o texto plano) y guardar aquellos que coincidan con una extensión de dominio (TLD, Top Level Domain) especificada por el usuario en un archivo CSV.
Esta funcionalidad es útil para listar los dominios peligrosos de tu base de datos como los .ru, .cn… o de países que no quieras que estén en tu lista por motivos de idioma, por ejemplo. Después esa lista de dominios puedes utilizarla como blacklist para tu gestor de listas de correo.
Copia y pega el contenido de este bloque en un fichero de texto que puedes llamar extraeredominios.py:
import re
import csv
import os
import sys
import time
import pandas as pd
def extract_domains_from_text(content, tld):
email_regex = r'[a-zA-Z0-9._%+-]+@([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})'
all_emails = re.findall(email_regex, content)
filtered_domains = set()
for domain in all_emails:
if domain.endswith('.' + tld):
filtered_domains.add(domain)
print(f"\rEncontrados: {len(filtered_domains)} dominios coincidentes", end='', flush=True)
print("") # para asegurarse de que la siguiente salida comienza en una nueva línea
return filtered_domains, len(all_emails)
def extract_domains(file_path, tld):
_, file_extension = os.path.splitext(file_path)
try:
if file_extension == '.xlsx':
content = pd.read_excel(file_path, engine='openpyxl').to_string()
elif file_extension == '.csv':
content = pd.read_csv(file_path).to_string()
else: # .txt y otros formatos de texto plano
with open(file_path, 'r', encoding='utf-8', errors='replace') as file:
content = file.read()
return extract_domains_from_text(content, tld)
except Exception as e:
print(f"Ocurrió un error durante la extracción de los dominios: {str(e)}")
return set()
def save_domains_to_csv(domains, output_filename):
base_name, ext = os.path.splitext(output_filename)
counter = 1
while os.path.exists(output_filename):
output_filename = f"{base_name}_{counter}{ext}"
counter += 1
try:
with open(output_filename, 'w', newline='', encoding='utf-8') as csvfile:
writer = csv.writer(csvfile, delimiter=',')
for domain in domains:
writer.writerow([domain])
except Exception as e:
print(f"Ocurrió un error durante la escritura al CSV: {str(e)}")
def main():
if len(sys.argv) != 2:
print("Uso: python script_name.py [input_file_path]")
return
input_filepath = sys.argv[1]
if not os.path.exists(input_filepath):
print("El archivo de entrada no existe.")
return
tld = input("Introduce la extensión de dominio que deseas extraer (ej. ru, es): ").strip()
base_name, _ = os.path.splitext(input_filepath)
output_filename = f"{base_name}_{tld}_domains.csv"
print("Iniciando la extracción de dominios...")
start_time = time.time()
domains, total_emails = extract_domains(input_filepath, tld)
end_time = time.time()
elapsed_time = end_time - start_time
print(f"\nTotal de emails analizados: {total_emails}")
if domains:
save_domains_to_csv(domains, output_filename)
print(f"Los dominios han sido guardados en {output_filename}")
else:
print("No se encontraron dominios con la extensión proporcionada en el archivo.")
print(f"Proceso finalizado en {elapsed_time:.2f} segundos.")
if __name__ == "__main__":
main()
Ejemplos de uso
- Extraer dominios «.ru» de un archivo Excel:
python script_name.py path/to/data.xlsx
Cuando el script pida el TLD, se debe introducir:ru
.
Este uso sería adecuado si tienes un archivo Excel con correos electrónicos y deseas extraer todos los dominios «.ru». - Extraer dominios «.cn» de un archivo CSV:
python script_name.py path/to/data.csv
Ingresando cn cuando se pide el TLD.
Este escenario puede ser útil si tienes un archivo CSV con datos de contacto y deseas obtener todos los dominios «.cn».
Explicación del código
Vamos a revisar cada parte del código:
extract_domains_from_text(content, tld)
- Input:
content
(contenido del archivo como string) ytld
(extensión de dominio objetivo, por ejemplo, «com» o «org»). - Proceso: Usa una expresión regular para extraer todos los dominios de los correos encontrados y filtra aquellos que terminan con el TLD especificado, mostrando progreso en la terminal.
- Output: Conjunto (
set
) de dominios que coinciden y la cantidad total de correos encontrados.
extract_domains(file_path, tld)
- Input:
file_path
(ruta al archivo de entrada) ytld
(extensión de dominio a filtrar). - Proceso: Lee el archivo dependiendo de su extensión (
.xlsx
,.csv
o texto plano) y llama aextract_domains_from_text
pasando el contenido del archivo ytld
. - Output: Los mismos que
extract_domains_from_text
o un conjunto vacío si hay un error.
save_domains_to_csv(domains, output_filename)
- Input:
domains
(conjunto de dominios a guardar) youtput_filename
(nombre deseado para el archivo de salida). - Proceso: Verifica que no sobrescribirá un archivo existente ajustando el nombre si es necesario, y escribe los dominios en un archivo CSV.
- Output: Un archivo CSV con los dominios, o un mensaje de error si ocurre alguno durante la escritura.
main()
- Proceso: Verifica los argumentos de la línea de comando, pide al usuario el TLD deseado, llama a las funciones anteriormente mencionadas para extraer los dominios y guardarlos, e informa al usuario sobre el progreso y los resultados.
Bloque if __name__ == "__main__":
- Asegura que
main()
se ejecuta solo cuando el script es llamado directamente, no cuando es importado como un módulo.