Quel est le moyen le plus rapide de HTTP GET en Python?

613

Quel est le moyen le plus rapide de HTTP GET en Python si je sais que le contenu sera une chaîne? Je recherche dans la documentation une ligne rapide comme:

contents = url.get("http://example.com/foo/bar")

Mais tout ce que je peux trouver en utilisant Google est httplibet urllib- et je ne trouve pas de raccourci dans ces bibliothèques.

Est-ce que Python 2.5 standard a un raccourci sous une forme comme ci-dessus, ou dois-je écrire une fonction url_get?

  1. Je préférerais ne pas capturer la sortie du décorticage vers wgetou curl.
Frank Krueger
la source
J'ai trouvé ce dont j'avais besoin ici: stackoverflow.com/a/385411/1695680
ThorSummoner

Réponses:

872

Python 3:

import urllib.request
contents = urllib.request.urlopen("http://example.com/foo/bar").read()

Python 2:

import urllib2
contents = urllib2.urlopen("http://example.com/foo/bar").read()

Documentation pour urllib.requestet read.

Nick Presta
la source
44
Est-ce que tout est bien nettoyé? On dirait que je devrais appeler closeaprès toi read. Est-ce que c'est nécessaire?
Frank Krueger
4
C'est une bonne pratique de le fermer, mais si vous cherchez une doublure rapide, vous pouvez l'omettre. :-)
Nick Presta
28
L'objet retourné par urlopen sera supprimé (et finalisé, ce qui le ferme) lorsqu'il sort du domaine. Parce que Cpython est compté par référence, vous pouvez compter sur cela qui se produit immédiatement après le read. Mais un withbloc serait plus clair et plus sûr pour Jython, etc.
sah
8
Cela ne fonctionne pas avec les sites Web HTTPS uniquement. requestsfonctionne bien
OverCoder
6
Si vous utilisez Amazon Lambda et avez besoin d'obtenir une URL, la solution 2.x est disponible et intégrée. Cela semble également fonctionner avec https. Ce n'est rien de plus r = urllib2.urlopen("http://blah.com/blah")et puis text = r.read(). Il est synchronisé, il attend juste le résultat en "texte".
Fattie
412

Vous pouvez utiliser une bibliothèque appelée requêtes .

import requests
r = requests.get("http://example.com/foo/bar")

C'est assez simple. Ensuite, vous pouvez faire comme ceci:

>>> print(r.status_code)
>>> print(r.headers)
>>> print(r.content)
Alex K
la source
1
@JoeBlow rappelez-vous que vous devez importer les bibliothèques externes pour les utiliser
MikeVelazco
1
Presque toutes les bibliothèques Python peuvent être utilisées dans AWS Lambda. Pour Python pur, il vous suffit de "vendre" cette bibliothèque (copier dans les dossiers de votre module plutôt que de l'utiliser pip install). Pour les bibliothèques non pures, il y a une étape supplémentaire - vous avez besoin de pip installla bibliothèque sur une instance d'AWS Linux (la même variante de système d'exploitation lambdas s'exécute sous), puis copiez ces fichiers à la place afin d'avoir une compatibilité binaire avec AWS Linux. Les seules bibliothèques que vous ne pourrez pas toujours utiliser dans Lambda sont celles avec des distributions binaires uniquement, heureusement assez rares.
Chris Johnson
6
@lawphotog cela fonctionne avec python3, mais vous devez pip install requests.
akarilimano
Même la bibliothèque standard urllib2 recommande des demandes
Asfand Qazi
En ce qui concerne Lambda: si vous souhaitez utiliser des demandes dans les fonctions AWS Lambda. Il existe également une bibliothèque de requêtes boto3 préinstallée. from botocore.vendored import requests Utilisation response = requests.get('...')
kmjb
29

Si vous voulez que la solution avec httplib2 soit intégrée, pensez à instancier un objet Http anonyme

import httplib2
resp, content = httplib2.Http().request("http://example.com/foo/bar")
to-chomik
la source
19

Jetez un œil à httplib2 , qui - à côté de nombreuses fonctionnalités très utiles - fournit exactement ce que vous voulez.

import httplib2

resp, content = httplib2.Http().request("http://example.com/foo/bar")

Où le contenu serait le corps de la réponse (sous forme de chaîne) et resp contiendrait les en-têtes de statut et de réponse.

Cependant, il n'est pas inclus avec une installation standard de python (mais il ne nécessite que du python standard), mais cela vaut vraiment la peine d'être vérifié.

hennr
la source
6

C'est assez simple avec la puissante urllib3bibliothèque.

Importez-le comme ceci:

import urllib3

http = urllib3.PoolManager()

Et faites une demande comme celle-ci:

response = http.request('GET', 'https://example.com')

print(response.data) # Raw data.
print(response.data.decode('utf-8')) # Text.
print(response.status) # Status code.
print(response.headers['Content-Type']) # Content type.

Vous pouvez également ajouter des en-têtes:

response = http.request('GET', 'https://example.com', headers={
    'key1': 'value1',
    'key2': 'value2'
})

Plus d'informations peuvent être trouvées sur la documentation urllib3 .

urllib3est beaucoup plus sûr et plus facile à utiliser que le module intégré urllib.requestou les httpmodules et est stable.

Juniorized
la source
1
idéal pour le fait que vous pouvez facilement fournir un verbe HTTP
Tom
5

La solution de theller pour wget est vraiment utile, cependant, j'ai trouvé qu'elle n'imprimait pas la progression tout au long du processus de téléchargement. C'est parfait si vous ajoutez une ligne après la déclaration d'impression dans reporthook.

import sys, urllib

def reporthook(a, b, c):
    print "% 3.1f%% of %d bytes\r" % (min(100, float(a * b) / c * 100), c),
    sys.stdout.flush()
for url in sys.argv[1:]:
    i = url.rfind("/")
    file = url[i+1:]
    print url, "->", file
    urllib.urlretrieve(url, file, reporthook)
print
Xuan
la source
4

Voici un script wget en Python:

# From python cookbook, 2nd edition, page 487
import sys, urllib

def reporthook(a, b, c):
    print "% 3.1f%% of %d bytes\r" % (min(100, float(a * b) / c * 100), c),
for url in sys.argv[1:]:
    i = url.rfind("/")
    file = url[i+1:]
    print url, "->", file
    urllib.urlretrieve(url, file, reporthook)
print
theller
la source
4

Sans autres importations nécessaires, cette solution fonctionne (pour moi) - également avec https:

try:
    import urllib2 as urlreq # Python 2.x
except:
    import urllib.request as urlreq # Python 3.x
req = urlreq.Request("http://example.com/foo/bar")
req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36')
urlreq.urlopen(req).read()

J'ai souvent du mal à saisir le contenu lorsque je ne spécifie pas un "User-Agent" dans les informations d'en-tête. Ensuite, les demandes sont généralement annulées avec quelque chose comme: urllib2.HTTPError: HTTP Error 403: Forbiddenou urllib.error.HTTPError: HTTP Error 403: Forbidden.

michael_s
la source
4

Comment envoyer également des en-têtes

Python 3:

import urllib.request
contents = urllib.request.urlopen(urllib.request.Request(
    "https://api.github.com/repos/cirosantilli/linux-kernel-module-cheat/releases/latest",
    headers={"Accept" : 'application/vnd.github.full+json"text/html'}
)).read()
print(contents)

Python 2:

import urllib2
contents = urllib2.urlopen(urllib2.Request(
    "https://api.github.com",
    headers={"Accept" : 'application/vnd.github.full+json"text/html'}
)).read()
print(contents)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
la source
2

Si vous travaillez spécifiquement avec des API HTTP, il existe également des choix plus pratiques tels que Nap .

Par exemple, voici comment obtenir des informations sur Github depuis le 1er mai 2014 :

from nap.url import Url
api = Url('https://api.github.com')

gists = api.join('gists')
response = gists.get(params={'since': '2014-05-01T00:00:00Z'})
print(response.json())

Plus d'exemples: https://github.com/kimmobrunfeldt/nap#examples

Kimmo
la source
2

Excellentes solutions Xuan, Theller.

Pour qu'il fonctionne avec python 3, apportez les modifications suivantes

import sys, urllib.request

def reporthook(a, b, c):
    print ("% 3.1f%% of %d bytes\r" % (min(100, float(a * b) / c * 100), c))
    sys.stdout.flush()
for url in sys.argv[1:]:
    i = url.rfind("/")
    file = url[i+1:]
    print (url, "->", file)
    urllib.request.urlretrieve(url, file, reporthook)
print

En outre, l'URL que vous entrez doit être précédée d'un "http: //", sinon elle renvoie une erreur de type d'URL inconnue.

Akshar
la source
1

Pour python >= 3.6, vous pouvez utiliser dload :

import dload
t = dload.text(url)

Pour json:

j = dload.json(url)

Installer:
pip install dload

CONvid19
la source
0

En fait, en python, nous pouvons lire à partir d'URL comme à partir de fichiers, voici un exemple pour lire json à partir de l'API.

import json

from urllib.request import urlopen

with urlopen(url) as f:

resp = json.load(f)

return resp['some_key']
Katrych Taras
la source
Bien que nous vous remercions pour votre réponse, il serait préférable qu'elle apporte une valeur supplémentaire en plus des autres réponses. Dans ce cas, votre réponse n'apporte aucune valeur supplémentaire, car un autre utilisateur a déjà publié cette solution. Si une réponse précédente vous a été utile, vous devriez voter contre au lieu de répéter les mêmes informations.
Toby Speight
0

Si vous voulez une API de niveau inférieur:

import http.client

conn = http.client.HTTPSConnection('example.com')
conn.request('GET', '/')

resp = conn.getresponse()
content = resp.read()

conn.close()

text = content.decode('utf-8')

print(text)
Juniorized
la source