Pregunta

Estoy procesar una lista de miles de nombres de dominio de una DNSBL través de excavación, la creación de un archivo CSV de direcciones URL y direcciones IP. Este es un proceso que consume mucho tiempo que puede durar varias horas. DNSBL de mi servidor actualiza cada quince minutos. ¿Hay alguna manera de aumentar el rendimiento en mi script de Python para mantener el ritmo de actualizaciones del servidor?

Editar . El guión, conforme a lo solicitado

import re
import subprocess as sp

text = open("domainslist", 'r')
text = text.read()
text = re.split("\n+", text)

file = open('final.csv', 'w')

for element in text:
        try:
            ip = sp.Popen(["dig", "+short", url], stdout = sp.PIPE)
            ip = re.split("\n+", ip.stdout.read())
            file.write(url + "," + ip[0] + "\n")
        except:
            pass
¿Fue útil?

Solución

Bueno, es probable que la resolución de nombres que usted está tomando tanto tiempo. Si se cuenta a eso (es decir, si de alguna manera dig vuelto muy rápidamente), Python debe ser capaz de hacer frente a miles de entradas fácilmente.

Dicho esto, usted debe tratar de un enfoque roscado. Eso sería (teóricamente) resolver varias direcciones al mismo tiempo, en lugar de secuencialmente. Se podía así continúa utilizando excavación para eso, y debe ser trivial para modificar mi código de ejemplo a continuación para eso, pero, para hacer cosas interesantes (y es de esperar más Pythonic), vamos a utilizar un módulo existente para ello: dnspython

Así, instalarlo con:

sudo pip install -f http://www.dnspython.org/kits/1.8.0/ dnspython

Y luego probar algo parecido a lo siguiente:

import threading
from dns import resolver

class Resolver(threading.Thread):
    def __init__(self, address, result_dict):
        threading.Thread.__init__(self)
        self.address = address
        self.result_dict = result_dict

    def run(self):
        try:
            result = resolver.query(self.address)[0].to_text()
            self.result_dict[self.address] = result
        except resolver.NXDOMAIN:
            pass


def main():
    infile = open("domainlist", "r")
    intext = infile.readlines()
    threads = []
    results = {}
    for address in [address.strip() for address in intext if address.strip()]:
        resolver_thread = Resolver(address, results)
        threads.append(resolver_thread)
        resolver_thread.start()

    for thread in threads:
        thread.join()

    outfile = open('final.csv', 'w')
    outfile.write("\n".join("%s,%s" % (address, ip) for address, ip in results.iteritems()))
    outfile.close()

if __name__ == '__main__':
    main()

Si eso prueba para comenzar a demasiados hilos al mismo tiempo, usted podría intentar hacerlo en lotes, o el uso de una cola (ver http://www.ibm.com/developerworks/aix/library/au-threadingpython/ para un ejemplo)

Otros consejos

La gran mayoría de las veces aquí se gasta en las llamadas externas a dig, por lo que para mejorar la velocidad, usted tendrá que multihilo. Esto le permitirá ejecutar varias llamadas a dig al mismo tiempo. Véase, por ejemplo: Python subprocess.Popen de un hilo. O bien, puede utilizar trenzado ( http://twistedmatrix.com/trac/ ).

EDIT:. Tiene razón, gran parte de eso era innecesario

Me volvería a considerar el uso de una biblioteca pura en Python para hacer las consultas DNS, en lugar de delegar en dig, debido a la invocación de otro proceso puede ser relativamente mucho tiempo. (Por supuesto, mirando cualquier cosa en Internet también es relativamente mucho tiempo, así que lo que gilesc dicho sobre multithreading todavía se aplica) Una búsqueda en Google para pitón DNS le dará algunas opciones para empezar a utilizar.

Con el fin de seguir el ritmo de las actualizaciones de servidor, hay que tener menos de 15 minutos en ejecutarse. ¿Su escritura de tomar 15 minutos para correr? Si no toma 15 minutos, ya está!

Yo investigaría almacenamiento en caché y las diferenciaciones de las ejecuciones anteriores con el fin de aumentar el rendimiento.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top