2009-03-14 16 views
397

¿Cuál es la forma más rápida de HTTP GET en Python si sé que el contenido será una cadena? Estoy buscando los documentos para un rápido de una sola línea como:¿Cuál es la forma más rápida de HTTP GET en Python?

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

Pero todo lo que puedo encontrar a través de Google son httplib y urllib - y yo soy incapaz de encontrar un acceso directo en esas bibliotecas.

¿Tiene el Python 2.5 estándar un atajo de alguna forma como el anterior, o debería escribir una función url_get?

  1. yo preferiría no capturar la salida de los bombardeos a cabo a wget o curl.
+20

Las líneas simples no son necesariamente más rápidas. No fetichice el código de golf. Tienes que medir la velocidad; no líneas de código –

+69

uhm, no, busqué en Google aquí porque necesitaba agregar una línea a un experimento que estoy escribiendo; no el producto terminado ¡El tiempo de CPU es mucho, mucho más barato que el tiempo del programador! – Phlip

+0

Encontré lo que necesitaba aquí: http://stackoverflow.com/a/385411/1695680 – ThorSummoner

Respuesta

594

Python 2.x:

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

Python 3.x:

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

Documentación para urllib.request y read.

¿Cómo es eso?

+25

¿Todo se limpia muy bien? Parece que debería llamar 'cerrar' después de su' lectura'. ¿Es eso necesario? –

+4

Es una buena práctica cerrarlo, pero si está buscando una línea rápida, podría omitirla. :-) –

+0

Por lo que vale, lo mismo funciona con urllib en lugar de urllib2 (al menos para la mayoría de las URL). –

17

Eche un vistazo a httplib2 que, junto con muchas funciones muy útiles, proporciona exactamente lo que desea.

import httplib2 

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

Donde el contenido sería el cuerpo de respuesta (como una cadena), y resp contendría el estado y los encabezados de respuesta.

Aunque no viene incluido con una instalación de python estándar (pero solo requiere una python estándar), pero definitivamente vale la pena echarle un vistazo.

27

Si desea solución con httplib2 sea oneliner considerar instatntinating objeto HTTP anónima

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

Aquí está una secuencia de comandos wget en Python: solución

# 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 
6

de Theller para wget es realmente útil, sin embargo, Descubrí que no imprime el progreso durante todo el proceso de descarga. Es perfecto si agrega una línea después de la declaración de impresión en el 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 
267

Puede utilizar una biblioteca llamada requests.

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

Esto es bastante fácil. A continuación, puede hacer así:

>>> print r.status_code 
>>> print r.headers 
>>> print r.content 
+2

Noté que esto no está disponible en Amazon Lambda ... – Fattie

+0

@JoeBlow Recuerde que debe importar las bibliotecas externas para usarlas – MikeVelazco

+0

Casi cualquier biblioteca de Python se puede usar en AWS Lambda. Para Python puro, solo necesita "vender" esa biblioteca (copiarla en las carpetas de su módulo en lugar de usar 'pip install'). Para las bibliotecas no puras, hay un paso adicional: debe instalar '' pip'' la lib en una instancia de AWS Linux (se ejecuta la misma variante de sistema operativo lambdas), luego copie esos archivos para que tenga compatibilidad binaria con AWS Linux. Las únicas bibliotecas que no siempre podrás usar en Lambda son aquellas con distribuciones binarias solamente, que afortunadamente son bastante raras. –

2

Si está trabajando con las API HTTP específicamente, también hay opciones más convenientes tales como Nap.

Por ejemplo, aquí es cómo conseguir los GIST de Github desde 1 ª de mayo de 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()) 

Más ejemplos: https://github.com/kimmobrunfeldt/nap#examples

3

excelentes soluciones Xuan, Theller.

Para que funcione con Python 3 Modifique la siguiente

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 

Además, el URL que introduzca debe ser precedida por una "http: //", de lo contrario, devuelve un error de tipo URL desconocida.

1

Sin más importaciones necesarias funciona esta solución (para mí) - también con 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() 

que a menudo tienen dificultades para agarrar el contenido cuando no se especifica un "User-Agent" en la información del encabezado. Entonces generalmente las solicitudes se cancelan con algo como: urllib2.HTTPError: HTTP Error 403: Forbidden o urllib.error.HTTPError: HTTP Error 403: Forbidden.

Cuestiones relacionadas