J'essaie de télécharger et d'enregistrer une image à partir du Web à l'aide du requests
module de python .
Voici le code (de travail) que j'ai utilisé:
img = urllib2.urlopen(settings.STATICMAP_URL.format(**data))
with open(path, 'w') as f:
f.write(img.read())
Voici le nouveau code (non fonctionnel) utilisant requests
:
r = requests.get(settings.STATICMAP_URL.format(**data))
if r.status_code == 200:
img = r.raw.read()
with open(path, 'w') as f:
f.write(img)
Pouvez-vous m'aider sur quel attribut de la réponse utiliser requests
?
python
urllib2
python-requests
shkschneider
la source
la source
Réponses:
Vous pouvez soit utiliser l'
response.raw
objet fichier , soit parcourir la réponse.Utiliser l'
response.raw
objet de type fichier ne décode pas, par défaut, les réponses compressées (avec GZIP ou dégonfler). Vous pouvez quand même le forcer à décompresser pour vous en définissant l'decode_content
attribut surTrue
(lerequests
définit surFalse
pour contrôler le décodage lui-même). Vous pouvez ensuite utilisershutil.copyfileobj()
pour que Python diffuse les données vers un objet fichier:Pour parcourir la réponse, utilisez une boucle; itérer comme ceci garantit que les données sont décompressées à cette étape:
Cela lira les données en blocs de 128 octets; si vous pensez qu'une autre taille de bloc fonctionne mieux, utilisez la
Response.iter_content()
méthode avec une taille de bloc personnalisée:Notez que vous devez ouvrir le fichier de destination en mode binaire pour vous assurer que python n'essaie pas de traduire les nouvelles lignes pour vous. Nous avons également configuré
stream=True
ce quirequests
ne télécharge pas l'image entière en mémoire en premier.la source
r2 = requests.post(r.url, data); print r2.content
. Mais maintenant, je veux aussi savoirfilename
. est leur moyen nettoyé? - actuellement, j'ai trouvé le nom du fichier dans l'en-tête -r2.headers['content-disposition']
cela me donne la sortie sous la forme:'attachment; filename=DELS36532G290115.csi'
je suis en train d'analyser cette chaîne pour le nom de fichier ... est-ce que leur manière est plus propre?content-disposition
tête est le chemin à parcourir ici; utilisercgi.parse_header()
pour l'analyser et obtenir les paramètres;params = cgi.parse_header(r2.headers['content-disposition'])[1]
alorsparams['filename']
.requests.Response
même :for chunk in r: ...
. Appeleriter_content()
sanschunk_size
volonté itérera en morceaux de 1 octet .response.ok
n'a jamais été documentée, et elle produit vrai pour n'importe quel état 1xx, 2xx ou 3xx, mais seule une réponse 200 a un corps de réponse.Obtenez un objet de type fichier à partir de la demande et copiez-le dans un fichier. Cela évitera également de lire le tout en mémoire à la fois.
la source
r.raw.decode_content = True
avantshutil.copyfileobj(response.raw, out_file)
carby default, decode compressed responses (with GZIP or deflate)
, vous obtiendrez donc une image sans fichier.Que diriez-vous de cela, une solution rapide.
la source
f = open("/Users/apple/Desktop/sample.jpg", 'wb')
que voulez-vous dire par ce chemin!? je veux télécharger l'imageif response.ok:
J'ai le même besoin de télécharger des images à l'aide de requêtes. J'ai d'abord essayé la réponse de Martijn Pieters, et cela fonctionne bien. Mais quand j'ai fait un profil sur cette fonction simple, j'ai trouvé qu'elle utilise autant d'appels de fonction par rapport à urllib et urllib2.
J'ai ensuite essayé la voie recommandée par l'auteur du module requêtes:
Cela a beaucoup plus réduit le nombre d'appels de fonction, accélérant ainsi mon application. Voici le code de mon profileur et le résultat.
Le résultat de testRequest:
Et le résultat de testRequest2:
la source
chunk_size
paramètre par défaut à 1, de même que l'iter_content
itération sur le flux de résultat 1 octet à la fois. Voir la documentation python-requests.org/en/latest/api/… .PIL
ici, c'est justewith open(image_name, 'wb') as outfile: outfile.write(r.content)
assez.PIL
n'est pas non plus dans la bibliothèque standard, ce qui le rend un peu moins portable.iter_content
est lent parce que le vôtrechunk_size
est trop petit, si vous l'augmentez à 100k, ce sera beaucoup plus rapide.Cela pourrait être plus facile que d'utiliser
requests
. C'est la seule fois que je proposerai de ne pas utiliserrequests
pour faire des trucs HTTP.Deux doublures utilisant
urllib
:Il y a aussi un joli module Python nommé
wget
qui est assez facile à utiliser. Trouvé ici .Cela démontre la simplicité de la conception:
Prendre plaisir.
Modifier: vous pouvez également ajouter un
out
paramètre pour spécifier un chemin.la source
wget
sans tracas. Merci d'avoir déclaré les avantages de l'utilisationurllib3
urllib.request.urlretrieve("http://example.com", "file.ext")
.L'extrait de code suivant télécharge un fichier.
Le fichier est enregistré avec son nom de fichier comme dans l'URL spécifiée.
la source
Il existe 2 façons principales:
En utilisant
.content
(le plus simple / officiel) (voir la réponse de Zhenyi Zhang ):Utilisation
.raw
(voir la réponse de Martijn Pieters ):Le timing ne montre aucune différence notable.
la source
1.
réponse (en utilisantio.BytesIO
etImage
) a été la première à fonctionner pour moi sur Python 3.6. N'oubliez pasfrom PIL import Image
(etpip install Pillow
).Aussi simple que d'importer une image et des requêtes
la source
Voici une réponse plus conviviale qui utilise toujours le streaming.
Définissez simplement ces fonctions et appelez
getImage()
. Il utilisera le même nom de fichier que l'URL et écrit dans le répertoire courant par défaut, mais les deux peuvent être modifiés.Les
request
tripes degetImage()
sont basées sur la réponse ici et les tripes degetImageFast()
sont basées sur la réponse ci-dessus .la source
Je vais poster une réponse car je n'ai pas assez de représentant pour faire un commentaire, mais avec wget tel que publié par Blairg23, vous pouvez également fournir un paramètre de sortie pour le chemin.
la source
Il s'agit de la première réponse qui apparaît pour les recherches Google sur la façon de télécharger un fichier binaire avec des demandes. Si vous devez télécharger un fichier arbitraire avec des demandes, vous pouvez utiliser:
la source
.close()
. C'est la meilleure réponse à partir de 2019, je suppose.C'est comme ça que je l'ai fait
la source
Vous pouvez faire quelque chose comme ça:
la source