¿Cuál es la forma más rápida de HTTP GET en Python?


613

¿Cuál es la forma más rápida de HTTP GET en Python si sé que el contenido será una cadena? Estoy buscando en la documentación una línea rápida como:

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

Pero todo lo que puedo encontrar usando Google son httpliby urllib, y no puedo encontrar un acceso directo en esas bibliotecas.

¿Python 2.5 estándar tiene un acceso directo en alguna forma como se indicó anteriormente, o debería escribir una función url_get?

  1. Preferiría no capturar la salida del bombardeo hacia wgeto curl.

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

Respuestas:


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()

Documentación para urllib.requesty read.


44
¿Todo se limpia bien? Parece que debería llamarte closedespués read. ¿Es eso necesario?
Frank Krueger el

44
Es una buena práctica cerrarlo, pero si está buscando una línea rápida, puede omitirla. :-)
Nick Presta

28
El objeto devuelto por urlopen se eliminará (y finalizará, lo que lo cierra) cuando quede fuera de alcance. Debido a que Cpython cuenta con referencias, puede confiar en que eso suceda inmediatamente después de read. Pero un withbloqueo sería más claro y seguro para Jython, etc.
sah

8
No funciona con sitios web solo HTTPS. requestsfunciona bien
OverCoder

66
Si está utilizando Amazon Lambda y necesita obtener una URL, la solución 2.x está disponible e incorporada. Parece funcionar también con https. No es nada más que r = urllib2.urlopen("http://blah.com/blah")y luego text = r.read(). Es sincronización, solo espera el resultado en "texto".
Fattie

412

Podría usar una biblioteca llamada solicitudes .

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

Esto es bastante facil. Entonces puedes hacer esto:

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

1
@JoeBlow recuerda que debes importar las bibliotecas externas para usarlas
MikeVelazco

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

66
@lawphotog esto FUNCIONA con python3, pero tienes que hacerlo pip install requests.
akarilimano

Incluso la biblioteca estándar urllib2 recomienda solicitudes
Asfand Qazi

En lo que respecta a Lambda: si desea utilizar solicitudes en las funciones de AWS Lambda. También hay una biblioteca de solicitudes de boto3 preinstalada. from botocore.vendored import requests Uso response = requests.get('...')
kmjb

29

Si desea que la solución con httplib2 sea única, considere crear instancias de un objeto Http anónimo

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

19

Eche un vistazo a httplib2 , que, junto a 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 los encabezados de estado y respuesta.

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


6

Es bastante simple con el poderoso urllib3 biblioteca.

Importarlo así:

import urllib3

http = urllib3.PoolManager()

Y haga una solicitud como esta:

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.

También puedes agregar encabezados:

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

Se puede encontrar más información en la documentación de urllib3 .

urllib3es mucho más seguro y fácil de usar que el integrado urllib.requesto los httpmódulos y es estable.


1
genial por el hecho de que puede proporcionar fácilmente un verbo HTTP
Tom

5

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

4

Aquí hay 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

Sin más importaciones necesarias, esta solución funciona (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()

A menudo tengo dificultades para obtener el contenido cuando no especifico un "Agente de usuario" en la información del encabezado. Luego, generalmente, las solicitudes se cancelan con algo como: urllib2.HTTPError: HTTP Error 403: Forbiddeno urllib.error.HTTPError: HTTP Error 403: Forbidden.


4

Cómo enviar también encabezados

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)

2

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

Por ejemplo, aquí le mostramos cómo obtener lo esencial de Github desde el 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


2

Excelentes soluciones Xuan, Theller.

Para que funcione con Python 3, realice los siguientes cambios

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, la URL que ingrese debe ir precedida de un "http: //", de lo contrario, devolverá un error de tipo de URL desconocido.


1

Para python >= 3.6, puedes usar dload :

import dload
t = dload.text(url)

Para json:

j = dload.json(url)

Instalar en pc:
pip install dload


0

En realidad, en Python podemos leer desde urls como desde archivos, aquí hay un ejemplo para leer json desde API.

import json

from urllib.request import urlopen

with urlopen(url) as f:

resp = json.load(f)

return resp['some_key']

Aunque le agradecemos su respuesta, sería mejor si proporcionara un valor adicional además de las otras respuestas. En este caso, su respuesta no proporciona un valor adicional, ya que otro usuario ya publicó esa solución. Si una respuesta anterior fue útil para usted, debe votarla en lugar de repetir la misma información.
Toby Speight

0

Si quieres una API de nivel inferior:

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)
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.