requête http avec un délai d'expiration, la taille maximale de connexion et de mise en commun
Je suis à la recherche d'un moyen en Python (2.7) pour faire des requêtes HTTP avec 3 exigences:
- délai d'attente (pour la fiabilité)
- contenu taille maximale (pour la sécurité)
- le regroupement de connexion (pour la performance)
J'ai vérifié tout à fait tous les python HTTP librairies, mais aucun d'entre eux répondre à mes exigences. Par exemple:
urllib2: bon, mais pas de mise en commun
import urllib2
import json
r = urllib2.urlopen('https://github.com/timeline.json', timeout=5)
content = r.read(100+1)
if len(content) > 100:
print 'too large'
r.close()
else:
print json.loads(content)
r = urllib2.urlopen('https://github.com/timeline.json', timeout=5)
content = r.read(100000+1)
if len(content) > 100000:
print 'too large'
r.close()
else:
print json.loads(content)
demandes: aucun taille max
import requests
r = requests.get('https://github.com/timeline.json', timeout=5, stream=True)
r.headers['content-length'] # does not exists for this request, and not safe
content = r.raw.read(100000+1)
print content # ARF this is gzipped, so not the real size
print json.loads(content) # content is gzipped so pretty useless
print r.json() # Does not work anymore since raw.read was used
urllib3: n'a jamais eu la "lecture" de la méthode de travail, même avec un fichier de 50Mo ...
httplib: httplib.HTTPConnection n'est pas une piscine (une seule connexion)
Je peux à peine croire que urllib2 est la meilleure HTTP bibliothèque je peux l'utiliser ! Donc si quelqu'un sait de quoi librairie peut faire ou comment faire pour utiliser l'une des précédentes librairie ...
EDIT:
La meilleure solution que j'ai trouvé grâce à Martijn Pieters (StringIO ne ralentit pas, même pour de gros fichiers, où str outre fait beaucoup).
r = requests.get('https://github.com/timeline.json', stream=True)
size = 0
ctt = StringIO()
for chunk in r.iter_content(2048):
size += len(chunk)
ctt.write(chunk)
if size > maxsize:
r.close()
raise ValueError('Response too large')
content = ctt.getvalue()
ctt.write(chunk)
ligne, je reçois un TypeError: string argument expected, got 'bytes'
OriginalL'auteur Aurélien Lambert | 2014-05-07
Vous devez vous connecter pour publier un commentaire.
Vous pouvez le faire avec
requests
juste bien; mais vous devez savoir que laraw
objet fait partie de l'urllib3
tripes et faire usage de l'argument supplémentaire de laHTTPResponse.read()
appel prend en charge, qui permet de spécifier que vous souhaitez lire décodé de données:Alternativement, vous pouvez définir la
decode_content
drapeau sur laraw
objet avant de le lire:Si vous n'aimez pas atteindre
urllib3
tripes comme ça, utiliser leréponse.iter_content()
pour parcourir le contenu décodé en morceaux; il utilise le sous-jacentHTTPResponse
trop (à l'aide de la.stream()
générateur de version:Il y a de la subtile différence dans la façon dont les données compressées tailles sont traitées ici;
r.raw.read(100000+1)
ne jamais lire de 100k octets de données compressées; les données non compressées est testé par rapport à votre taille max. Leiter_content()
méthode lire en plus des données non compressées dans les rares cas où le flux compressé est plus que les données non compressées.Ni méthode permet
r.json()
au travail; laresponse._content
attribut n'est pas défini par les présentes; vous pouvez le faire manuellement bien sûr. Mais depuis le.raw.read()
et.iter_content()
appelle déjà vous donner accès à du contenu en question, il n'y a vraiment pas besoin.urllib2
n'accepte pas de compression,r.raw.read
comparer le format la taille etr.iter_content
comparer la taille réelle, mais vraiment ralentir le code (peut-être un flux de rendre plus rapide).combien
r.iter_content()
ralentit le code dépend entièrement de la taille des blocs de lecture; un petit morceau de la taille nécessite plus d'itérations de boucle. Et il fonctionne sur un stream déjà.Le
content += chunk
ralentir en raison de python str non de la mutabilité. StringIO.StringIO résolu.Oui, j'ai contemplé l'aide d'une liste au lieu de cela, puis
''.join()
à la fin, maisStringIO()
encapsule bien.Pour quiconque d'essayer ce sur Python3 notez que vous aurez besoin
content = b''
+1OriginalL'auteur Martijn Pieters