2012-05-11 4 views
7

Eventuali duplicati:
Multiple (asynchronous) connections with urllib2 or other http library?Metodo ideale per inviare più richieste HTTP su Python?

Sto lavorando su un web server Linux che esegue il codice Python per afferrare dati in tempo reale su HTTP da un 3 ° API partito. I dati vengono inseriti in un database MySQL. Ho bisogno di fare molte domande a molti URL, e ho bisogno di farlo velocemente (più veloce = meglio). Attualmente sto usando urllib3 come libreria HTTP. Qual è il modo migliore per farlo? Devo generare più thread (se sì, quanti?) E avere ogni query per un URL diverso? Mi piacerebbe sentire i tuoi pensieri su questo - grazie!

risposta

23

Se molto è davvero molto di quanto probabilmente si desidera utilizzare non io asincrono discussioni.

requests + gevent = grequests

GRequests consente di utilizzare richieste con Gevent di effettuare richieste HTTP asincrone facilmente.

import grequests 

urls = [ 
    'http://www.heroku.com', 
    'http://tablib.org', 
    'http://httpbin.org', 
    'http://python-requests.org', 
    'http://kennethreitz.com' 
] 

rs = (grequests.get(u) for u in urls) 
grequests.map(rs) 
+1

Voglio usare questo metodo per inviare richieste a circa 50.000 url. È una buona strategia? Inoltre, che dire delle eccezioni come il timeout, ecc.? – John

+0

@John Sì, lo è. Per quanto riguarda le eccezioni vedi il parametro ['safe_mode'] (http://requests.readthedocs.org/en/latest/api/) e il problema [953] (https://github.com/kennethreitz/requests/pull/953) –

+5

Non posso inviare più di 30 richieste utilizzando grequest. Quando lo faccio, ricevo "Max tentativi superati con url: ..., Troppi file aperti". C'è comunque un modo per risolvere questo problema? – AliBZ

1

È necessario utilizzare il multithreading e le richieste di pipeline. Ad esempio cerca-> dettagli-> salva

Il numero di fili che è possibile utilizzare non dipende solo dall'attrezzatura. Quante richieste può servire il servizio? Quante richieste simultanee consente di eseguire? Anche la larghezza di banda può essere un collo di bottiglia.

Se si parla di una sorta di scraping, il servizio potrebbe bloccarti dopo un certo limite di richieste, quindi è necessario utilizzare proxy o più collegamenti IP.

Per quanto mi riguarda, nella maggior parte dei casi, posso eseguire da 50 a 300 richieste simultanee sul mio laptop da script Python.

+0

D'accordo con Polscha, qui. La maggior parte delle volte, quando si effettuano richieste HTTP a un servizio arbitrario, la maggior parte del tempo (di orologio) impiegato è in attesa che la rete e il servizio remoto rispondano. Quindi, entro limiti ragionevoli, più thread, meglio è come in un dato momento, la maggior parte di questi thread sarà solo in attesa. Sicuramente tiene conto delle note di Polscha sulla limitazione del servizio. – parselmouth

+0

grazie ragazzi - il servizio è commerciale e lo stiamo pagando. è molto veloce e non sarà il collo di bottiglia. in questo caso, quale sarebbe l'opzione migliore? – user1094786

+0

@ user1094786 In questo caso, provare a creare una pipeline di richieste e sperimentare un numero di thread su ogni fase. Prova, prima o poi troverai il limite superiore :-) –

0

Sembra un'eccellente applicazione per Twisted. Ecco alcuni web-related examples, incluso come download a web page. Ecco una domanda correlata su database connections with Twisted.

Nota che Twisted fa non contare su thread per fare più cose contemporaneamente. Piuttosto, ci vuole un approccio cooperative multitasking --- il tuo script principale avvia il reattore e il reattore chiama le funzioni che hai impostato. Le tue funzioni devono restituire il controllo al reattore prima che il reattore possa continuare a funzionare.