Domanda

Sto elaborando un elenco di migliaia di nomi di dominio da un DNSBL tramite dig, creando un CSV di URL e IP.Questo è un processo molto dispendioso in termini di tempo che può richiedere diverse ore.Il DNSBL del mio server si aggiorna ogni quindici minuti.Esiste un modo per aumentare la velocità effettiva nel mio script Python per tenere il passo con gli aggiornamenti del server?

Modificare:lo script, come richiesto.

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
È stato utile?

Soluzione

Beh, probabilmente è la risoluzione del nome che ti sta portando via così tanto tempo.Se lo conti (cioè se in qualche modo dig ritorna molto rapidamente), Python dovrebbe essere in grado di gestire facilmente migliaia di voci.

Detto questo, dovresti provare un approccio threaded.Ciò risolverebbe (teoricamente) più indirizzi contemporaneamente, anziché in sequenza.Potresti anche continuare a usare dig per quello, e dovrebbe essere banale modificare il mio codice di esempio qui sotto per quello, ma, per rendere le cose interessanti (e, si spera, più pitoniche), usiamo un modulo esistente per quello: dnspython

Quindi, installalo con:

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

E poi prova qualcosa di simile a quanto segue:

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()

Se ciò dimostra di avviare troppi thread contemporaneamente, potresti provare a farlo in batch o utilizzando una coda (vedi http://www.ibm.com/developerworks/aix/library/au-threadingpython/ per un esempio)

Altri suggerimenti

La maggior parte del tempo qui è speso nelle chiamate esterne a dig, in modo da migliorare la velocità, avrete bisogno di multithread. Questo vi permetterà di eseguire più chiamate a dig allo stesso tempo. Si veda ad esempio: Python subprocess.Popen da un filo . In alternativa, è possibile utilizzare ritorto ( http://twistedmatrix.com/trac/ ).

EDIT:. Siete sulla strada giusta, gran parte di questo era inutile

mi piacerebbe considerare l'utilizzo di una libreria puro Python per fare le query DNS, piuttosto che delegare a dig, perché invocando un altro processo può essere relativamente molto tempo. (Naturalmente, guardando qualcosa su Internet è anche relativamente in termini di tempo, così che cosa gilesc detto a proposito multithreading si applica ancora) una ricerca su Google per python dns vi darà alcune opzioni per iniziare con.

Al fine di tenere il passo con gli aggiornamenti del server, si deve prendere meno di 15 minuti per l'esecuzione. Il vostro script di prendere 15 minuti per correre? Se non ci vuole 15 minuti, il gioco è fatto!

vorrei indagare caching e diff di precedenti esecuzioni al fine di aumentare le prestazioni.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top