¿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.
Frank Krueger
fuente
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.

Nick Presta
fuente
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)
Alex K
fuente
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")
to-chomik
fuente
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.

hennr
fuente
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.

Juniorized
fuente
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
Xuan
fuente
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
theller
fuente
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.

michael_s
fuente
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)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
fuente
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

Kimmo
fuente
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.

Akshar
fuente
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

CONvid19
fuente
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']
Katrych Taras
fuente
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)
Juniorized
fuente