2010-03-04 4 views
2

J'ai une grosse liste d'URL, que je dois télécharger en parallèle et cocher l'un des en-têtes qui est retourné avec chaque réponse.pycurl et beaucoup de fonctions de rappel

Je peux utiliser CurlMulti pour la parallélisation. Je peux utiliser /dev/null comme fb, parce que je ne suis pas intéressé par le corps, seuls les en-têtes. Mais comment puis-je vérifier chaque en-tête?

Pour recevoir l'en-tête, je dois définir le rappel HEADERFUNCTION. Je comprends ça.

Mais dans cette fonction de rappel je reçois seulement un tampon avec en-têtes. Comment puis-je distinguer une demande d'une autre?

Je n'aime pas l'idée de créer autant de fonctions de rappel que d'URL. Devrais-je créer une classe et autant d'instances de cette classe? Aussi pas très intelligent.

Répondre

0

La solution consiste à utiliser un peu de programmation fonctionnelle pour «coller» des informations supplémentaires à notre fonction de rappel.

functools.partial

0

Je sais que vous posez des questions sur le pycurl, mais je le trouve trop dur et non-pythonique à utiliser. L'API est bizarre.

Voici un exemple twisted:

from twisted.web.client import Agent 
from twisted.internet import reactor, defer 

def get_headers(response, url): 
    '''Extract a dict of headers from the response''' 
    return url, dict(response.headers.getAllRawHeaders()) 

def got_everything(all_headers): 
    '''print results and end program''' 
    print dict(all_headers) 
    reactor.stop() 

agent = Agent(reactor) 
urls = (line.strip() for line in open('urls.txt')) 
reqs = [agent.request('HEAD', url).addCallback(get_headers, url) for url in urls if url] 
defer.gatherResults(reqs).addCallback(got_everything) 
reactor.run() 

Cet exemple commence toutes les demandes de manière asynchrone, et rassembler tous les résultats. Voici la sortie d'un fichier avec 3 urls:

{'http://debian.org': {'Content-Type': ['text/html; charset=iso-8859-1'], 
         'Date': ['Thu, 04 Mar 2010 13:27:25 GMT'], 
         'Location': ['http://www.debian.org/'], 
         'Server': ['Apache'], 
         'Vary': ['Accept-Encoding']}, 
'http://google.com': {'Cache-Control': ['public, max-age=2592000'], 
         'Content-Type': ['text/html; charset=UTF-8'], 
         'Date': ['Thu, 04 Mar 2010 13:27:25 GMT'], 
         'Expires': ['Sat, 03 Apr 2010 13:27:25 GMT'], 
         'Location': ['http://www.google.com/'], 
         'Server': ['gws'], 
         'X-Xss-Protection': ['0']}, 
'http://stackoverflow.com': {'Cache-Control': ['private'], 
           'Content-Type': ['text/html; charset=utf-8'], 
           'Date': ['Thu, 04 Mar 2010 13:27:24 GMT'], 
           'Expires': ['Thu, 04 Mar 2010 13:27:25 GMT'], 
           'Server': ['Microsoft-IIS/7.5']}} 
1

J'utiliser Python construit dans httplib et modules de filetage. Je ne vois pas le besoin d'un module tiers.

+0

Eh bien, la même raison que vous souhaitez utiliser Python et non C/ASM - pour rendre les choses plus facile/plus agréable. – nosklo

+0

Lorsque vous prenez en compte le type de recherche et d'apprentissage de l'utilisation d'un module tiers, il n'y a pas beaucoup d'économie pour un si petit problème. – mikerobi

+1

Ce n'est pas un argument. Vous devez également apprendre des modules intégrés pour que le temps passé soit le même. Et pour certains cas (comme celui-ci), vous obtiendrez un code de qualité inférieure. – nosklo