web-dev-qa-db-fra.com

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

Quel est le moyen le plus rapide de HTTP GET dans Python si je sais que le contenu sera une chaîne? Je cherche dans la documentation un one-liner rapide comme:

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

Mais tout ce que je peux trouver avec Google, ce sont httplib et urllib - et je suis incapable de trouver un raccourci dans ces bibliothèques.

La norme Python 2.5 a-t-elle un raccourci comme ci-dessus ou dois-je écrire une fonction url_get?

  1. Je préférerais ne pas capturer la sortie du shelling out en wget ou curl.
566
Frank Krueger

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.request et read .

814
Nick Presta

Vous pouvez utiliser une bibliothèque appelée demandes .

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

C'est assez facile. Ensuite, vous pouvez faire comme ça:

>>> print(r.status_code)
>>> print(r.headers)
>>> print(r.content)
383
user1001237

Si vous souhaitez que la solution avec httplib2 soit unique, envisagez l’instanciation d’un objet http anonyme.

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

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ù content serait le corps de la réponse (sous forme de chaîne), et resp contiendrait les en-têtes status et response.

Il n’est pas fourni avec une installation standard de python (mais il n’exige que python standard), mais cela vaut vraiment la peine d’y jeter un coup d’œil.

19
Steven

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 l'instruction print 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
5
Xuan

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: Forbidden ou urllib.error.HTTPError: HTTP Error 403: Forbidden.

4
michael_s

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
4
theller

C'est assez simple avec urllib3.

Importez-le comme ceci:

import urllib3

pool_manager = urllib3.PoolManager()

Et faites une demande comme ceci:

example_request = pool_manager.request("GET", "https://example.com")

print(example_request.data.decode("utf-8")) # Response text.
print(example_request.status) # Status code.
print(example_request.headers["Content-Type"]) # Content type.

Vous pouvez aussi ajouter des en-têtes:

example_request = pool_manager.request("GET", "https://example.com", headers = {
    "Header1": "value1",
    "Header2": "value2"
})
4
Juniorized

Comment envoyer aussi 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)

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

Par exemple, voici comment obtenir les idées de 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())

Autres exemples: https://github.com/kimmobrunfeldt/nap#examples

2
Kimmo

Excellentes solutions Xuan, Theller.

Pour que cela 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

De plus, l'URL que vous entrez doit être précédée d'un "http: //", sinon une erreur de type URL inconnue est renvoyée.

2
Akshar