El módulo de solicitudes de Python

E

Introducción

Tratar con solicitudes HTTP no es una tarea fácil en ningún lenguaje de programación. Si hablamos de Python, viene con dos módulos integrados, urllib y urllib2, para manejar operaciones relacionadas con HTTP. Ambos módulos vienen con un conjunto diferente de funcionalidades y muchas veces deben usarse juntos. El principal inconveniente de usar urllib es que es confuso (hay pocos métodos disponibles en ambos urllib, urllib2), la documentación no es clara y necesitamos escribir mucho código para realizar incluso una simple solicitud HTTP.

Para simplificar estas cosas, una biblioteca de terceros fácil de usar, conocida como Peticiones, está disponible y la mayoría de los desarrolladores prefieren usarlo en su lugar o urllib/urllib2. Es una biblioteca HTTP con licencia de Apache2 impulsada por urllib3 y httplib.

Instalación del módulo de solicitudes

Instalar este paquete, como la mayoría de los otros paquetes de Python, es bastante sencillo. Puede descargar el Solicita el código fuente desde Github e instálelo o use pip:

$ pip install requests

Para obtener más información sobre el proceso de instalación, consulte el documentación oficial.

Para verificar la instalación, puede intentar importarla como se muestra a continuación:

import requests

Si no recibe ningún error al importar el módulo, entonces fue exitoso.

Hacer una solicitud GET

GET es, con mucho, el método HTTP más utilizado. Podemos usar la solicitud GET para recuperar datos de cualquier destino. Permítanme comenzar con un ejemplo simple primero. Suponga que queremos obtener el contenido de la página de inicio de nuestro sitio web e imprimir el resultado en datos HTML. Usando el módulo de Solicitudes, podemos hacerlo como a continuación:

import requests

r = requests.get('https://api.github.com/events')
print(r.content)

Imprimirá la respuesta en forma codificada. Si desea ver el resultado de texto real de la página HTML, puede leer el .text propiedad de este objeto. Del mismo modo, el status_code property imprime el código de estado actual de la URL:

import requests

r = requests.get('https://api.github.com/events')
print(r.text)
print(r.status_code)

requests decodificará el contenido sin procesar y le mostrará el resultado. Si desea comprobar qué tipo de encoding es usado por requests, puede imprimir este valor llamando .encoding. Incluso el tipo de codificación se puede cambiar cambiando su valor. ¿No es así de simple?

Leer la respuesta

La respuesta de una solicitud HTTP puede contener muchos encabezados que contienen información diferente.

httpbin es un sitio web popular para probar diferentes operaciones HTTP. En este artículo usaremos httpbin / get para analizar la respuesta a una solicitud GET. En primer lugar, necesitamos averiguar el encabezado de respuesta y cómo se ve. Puede usar cualquier navegador web moderno para encontrarlo, pero para este ejemplo, usaremos el navegador Chrome de Google.

  • En Chrome, abra la URL http://httpbin.org/get, haga clic con el botón derecho en cualquier lugar de la página y seleccione la opción “Inspeccionar”
  • Esto abrirá una nueva ventana dentro de su navegador. Actualice la página y haga clic en la pestaña “Red”.
  • Esta pestaña “Red” le mostrará todos los diferentes tipos de solicitudes de red realizadas por el navegador. Haga clic en la solicitud “obtener” en la columna “Nombre” y seleccione la pestaña “Encabezados” a la derecha.

El contenido de los “Encabezados de respuesta” es nuestro elemento obligatorio. Puede ver los pares clave-valor que contienen información diversa sobre el recurso y la solicitud. Intentemos analizar estos valores usando el requests biblioteca:

import requests

r = requests.get('http://httpbin.org/get')
print(r.headers['Access-Control-Allow-Credentials'])
print(r.headers['Access-Control-Allow-Origin'])
print(r.headers['CONNECTION'])
print(r.headers['content-length'])
print(r.headers['Content-Type'])
print(r.headers['Date'])
print(r.headers['server'])
print(r.headers['via'])

Recuperamos la información del encabezado usando r.headers y podemos acceder a cada valor de encabezado usando claves específicas. Tenga en cuenta que la clave no distingue entre mayúsculas y minúsculas.

Del mismo modo, intentemos acceder al valor de respuesta. El encabezado anterior muestra que la respuesta está en formato JSON: (Content-type: application/json). La biblioteca de solicitudes viene con un analizador JSON incorporado y podemos usar requests.get('url').json() para analizarlo como un objeto JSON. Luego, el valor de cada clave de los resultados de respuesta se puede analizar fácilmente como se muestra a continuación:

import requests

r = requests.get('http://httpbin.org/get')

response = r.json()
print(r.json())
print(response['args'])
print(response['headers'])
print(response['headers']['Accept'])
print(response['headers']['Accept-Encoding'])
print(response['headers']['Connection'])
print(response['headers']['Host'])
print(response['headers']['User-Agent'])
print(response['origin'])
print(response['url'])

El código anterior imprimirá la siguiente salida:

{'headers': {'Host': 'httpbin.org', 'Accept-Encoding': 'gzip, deflate', 'Connection': 'close', 'Accept': '*/*', 'User-Agent': 'python-requests/2.9.1'}, 'url': 'http://httpbin.org/get', 'args': {}, 'origin': '103.9.74.222'}
{}
{'Host': 'httpbin.org', 'Accept-Encoding': 'gzip, deflate', 'Connection': 'close', 'Accept': '*/*', 'User-Agent': 'python-requests/2.9.1'}
*/*
gzip, deflate
close
httpbin.org
python-requests/2.9.1
103.9.74.222
http://httpbin.org/get

Tercera línea, es decir r.json(), imprimió el valor JSON de la respuesta. Hemos almacenado el valor JSON en la variable. response y luego imprime el valor de cada tecla. Tenga en cuenta que, a diferencia del ejemplo anterior, el valor-clave distingue entre mayúsculas y minúsculas.

Similar al JSON y al contenido de texto, podemos usar requests para leer el contenido de la respuesta en bytes para solicitudes que no son de texto usando el .content propiedad. Esto decodificará automáticamente gzip y deflate archivos codificados.

Pasar parámetros en GET

En algunos casos, deberá pasar parámetros junto con sus solicitudes GET, que toman la forma de cadenas de consulta. Para hacer esto, necesitamos pasar estos valores en el params parámetro, como se muestra a continuación:

import requests

payload = {'user_name': 'admin', 'password': 'password'}
r = requests.get('http://httpbin.org/get', params=payload)

print(r.url)
print(r.text)

Aquí, estamos asignando nuestros valores de parámetro a la payload variable, y luego a la solicitud GET a través de params. El código anterior devolverá el siguiente resultado:

http://httpbin.org/get?password=password&user_name=admin
{"args":{"password":"password","user_name":"admin"},"headers":{"Accept":"*/*","Accept-Encoding":"gzip, deflate","Connection":"close","Host":"httpbin.org","User-Agent":"python-requests/2.9.1"},"origin":"103.9.74.222","url":"http://httpbin.org/get?password=password&user_name=admin"}

Como puede ver, la biblioteca de Reqeusts convirtió automáticamente nuestro diccionario de parámetros en una cadena de consulta y lo adjuntó a la URL.

Tenga en cuenta que debe tener cuidado con el tipo de datos que pasa a través de las solicitudes GET, ya que la carga útil es visible en la URL, como puede ver en el resultado anterior.

Realización de solicitudes POST

Las solicitudes HTTP POST son opuestas a las solicitudes GET, ya que están destinadas a enviar datos a un servidor en lugar de recuperarlos. Aunque, las solicitudes POST también pueden recibir datos dentro de la respuesta, al igual que las solicitudes GET.

En lugar de utilizar el get() método, necesitamos usar el post() método. Para pasar un argumento, podemos pasarlo dentro del data parámetro:

import requests

payload = {'user_name': 'admin', 'password': 'password'}
r = requests.post("http://httpbin.org/post", data=payload)
print(r.url)
print(r.text)

Salida:

http://httpbin.org/post
{"args":{},"data":"","files":{},"form":{"password":"password","user_name":"admin"},"headers":{"Accept":"*/*","Accept-Encoding":"gzip, deflate","Connection":"close","Content-Length":"33","Content-Type":"application/x-www-form-urlencoded","Host":"httpbin.org","User-Agent":"python-requests/2.9.1"},"json":null,"origin":"103.9.74.222","url":"http://httpbin.org/post"}

Los datos estarán “codificados en formato” de forma predeterminada. También puede pasar solicitudes de encabezado más complicadas como una tupla si varios valores tienen la misma clave, una cadena en lugar de un diccionario o un archivo codificado de varias partes.

Envío de archivos con POST

A veces necesitamos enviar uno o más archivos simultáneamente al servidor. Por ejemplo, si un usuario envía un formulario y el formulario incluye diferentes campos de formulario para cargar archivos, como imagen de perfil de usuario, currículum vitae del usuario, etc. Las solicitudes pueden manejar varios archivos en una sola solicitud. Esto se puede lograr poniendo los archivos en una lista de tuplas, como se muestra a continuación:

import requests

url="http://httpbin.org/post"
file_list = [
    ('image', ('image1.jpg', open('image1.jpg', 'rb'), 'image/png')),
    ('image', ('image2.jpg', open('image2.jpg', 'rb'), 'image/png'))
]

r = requests.post(url, files=file_list)
print(r.text)

Las tuplas que contienen la información de los archivos tienen el formato (field_name, file_info).

Otros tipos de solicitudes HTTP

Similar a GET y POST, podemos realizar otras solicitudes HTTP como PUT, DELETE, HEAD y OPTIONS usando el requests biblioteca, como a continuación:

import requests

requests.put('url', data={'key': 'value'})
requests.delete('url')
requests.head('url')
requests.options('url')

Manejo de redirecciones

La redirección en HTTP significa reenviar la solicitud de red a una URL diferente. Por ejemplo, si hacemos una solicitud a “http://www.github.com“, redirigirá a”https://github.com” usando un Redireccionamiento 301.

import requests

r = requests.post("http://www.github.com")
print(r.url)
print(r.history)
print(r.status_code)

Salida:

https://github.com/
[<Response [301]>, <Response [301]>]
200

Como puede ver, el proceso de redirección lo maneja automáticamente requests, por lo que no es necesario que lo resuelva usted mismo. los history La propiedad contiene la lista de todos los objetos de respuesta creados para completar la redirección. En nuestro ejemplo, dos Response Los objetos se crearon con el código de respuesta 301. Las respuestas HTTP 301 y 302 se utilizan para la redirección permanente y temporal, respectivamente.

Si no desea que la biblioteca de solicitudes siga automáticamente las redirecciones, puede deshabilitarla pasando el allow_redirects=False junto con la solicitud.

Manejo de tiempos de espera

Otra configuración importante es decirle a nuestra biblioteca cómo manejar los tiempos de espera o las solicitudes que tardan demasiado en regresar. Podemos configurar requests para dejar de esperar las solicitudes de red utilizando el timeout parámetro. Por defecto, requests no se agotará el tiempo de espera. Por lo tanto, si no configuramos esta propiedad, nuestro programa puede bloquearse indefinidamente, que no es la funcionalidad que le gustaría en un proceso que hace esperar al usuario.

import requests

requests.get('http://www.google.com', timeout=1)

Aquí, se lanzará una excepción si el servidor no responde en 1 segundo (lo que sigue siendo agresivo para una aplicación del mundo real). Para que esto falle con más frecuencia (por ejemplo), debe establecer el límite de tiempo de espera en un valor mucho menor, como 0.001.

El tiempo de espera se puede configurar para las operaciones “conectar” y “leer” de la solicitud mediante una tupla, que le permite especificar ambos valores por separado:

import requests

requests.get('http://www.google.com', timeout=(5, 14))

Aquí, el tiempo de espera de “conexión” es de 5 segundos y el tiempo de espera de “lectura” es de 14 segundos. Esto permitirá que su solicitud falle mucho más rápidamente si no puede conectarse al recurso, y si se conecta, le dará más tiempo para descargar los datos.

Cookies y encabezados personalizados

Hemos visto anteriormente cómo acceder a los encabezados usando el headers propiedad. Del mismo modo, podemos acceder a las cookies desde una respuesta utilizando el cookies propiedad.

Por ejemplo, el siguiente ejemplo muestra cómo acceder a una cookie con nombre cookie_name:

import requests

r = requests.get('http://www.examplesite.com')
r.cookies['cookie_name']

También podemos enviar cookies personalizadas al servidor proporcionando un diccionario al cookies parámetro en nuestra solicitud GET.

import requests

custom_cookie = {'cookie_name': 'cookie_value'}
r = requests.get('http://www.examplesite.com/cookies', cookies=custom_cookie)

Las cookies también se pueden pasar en un Cookie Jar. Esto le permite proporcionar cookies para una ruta diferente.

import requests

jar = requests.cookies.RequestsCookieJar()
jar.set('cookie_one', 'one', domain='httpbin.org', path="/cookies")
jar.set('cookie_two', 'two', domain='httpbin.org', path="/other")

r = requests.get('https://httpbin.org/cookies', cookies=jar)
print(r.text)

Salida:

{"cookies":{"cookie_one":"one"}}

De manera similar, podemos crear encabezados personalizados asignando un diccionario al encabezado de la solicitud usando el headers parámetro.

import requests

custom_header = {'user-agent': 'customUserAgent'}

r = requests.get('https://samplesite.org', headers=custom_header)

El objeto de sesión

El objeto de sesión se utiliza principalmente para conservar ciertos parámetros, como cookies, en diferentes solicitudes HTTP. Un objeto de sesión puede usar una sola conexión TCP para manejar múltiples solicitudes y respuestas de red, lo que da como resultado una mejora del rendimiento.

import requests

first_session = requests.Session()
second_session = requests.Session()

first_session.get('http://httpbin.org/cookies/set/cookieone/111')
r = first_session.get('http://httpbin.org/cookies')
print(r.text)

second_session.get('http://httpbin.org/cookies/set/cookietwo/222')
r = second_session.get('http://httpbin.org/cookies')
print(r.text)

r = first_session.get('http://httpbin.org/anything')
print(r.text)

Salida:

{"cookies":{"cookieone":"111"}}

{"cookies":{"cookietwo":"222"}}

{"args":{},"data":"","files":{},"form":{},"headers":{"Accept":"*/*","Accept-Encoding":"gzip, deflate","Connection":"close","Cookie":"cookieone=111","Host":"httpbin.org","User-Agent":"python-requests/2.9.1"},"json":null,"method":"GET","origin":"103.9.74.222","url":"http://httpbin.org/anything"}

La ruta httpbin / cookies / set / {nombre} / {valor} establecerá una cookie con name y value. Aquí, establecemos diferentes valores de cookies para ambos first_session y second_session objetos. Puede ver que se devuelve la misma cookie en todas las solicitudes de red futuras para una sesión específica.

De manera similar, podemos usar el objeto de sesión para conservar ciertos parámetros para todas las solicitudes.

import requests

first_session = requests.Session()

first_session.cookies.update({'default_cookie': 'default'})

r = first_session.get('http://httpbin.org/cookies', cookies={'first-cookie': '111'})
print(r.text)

r = first_session.get('http://httpbin.org/cookies')
print(r.text)

Salida:

{"cookies":{"default_cookie":"default","first-cookie":"111"}}

{"cookies":{"default_cookie":"default"}}

Como puede ver, el default_cookie se envía con cada solicitud de la sesión. Si agregamos algún parámetro adicional al cookie objeto, se agrega al default_cookie. "first-cookie": "111" se agrega a la cookie predeterminada "default_cookie": "default"

Usando Proxies

los proxies El argumento se usa para configurar un servidor proxy para usar en sus solicitudes.

http = "http://10.10.1.10:1080"
https = "https://10.10.1.11:3128"
ftp = "ftp://10.10.1.10:8080"

proxy_dict = {
  "http": http,
  "https": https,
  "ftp": ftp
}

r = requests.get('http://sampleurl.com', proxies=proxy_dict)

los requests la biblioteca también admite SOCKS apoderados. Esta es una característica opcional y requiere la requests[socks] dependencia que se instalará antes de su uso. Como antes, puedes instalarlo usando pip:

$ pip install requests[socks]

Después de la instalación, puede usarlo como se muestra aquí:

proxies = {
  'http': 'socks5:user:[email protected]:port'
  'https': 'socks5:user:[email protected]:port'
}

Manejo SSL

También podemos utilizar la biblioteca de solicitudes para verificar el certificado HTTPS de un sitio web pasando verify=true con la solicitud.

import requests

r = requests.get('https://www.github.com', verify=True)

Esto arrojará un error si hay algún problema con el SSL del sitio. Si no quieres la verdad, pasa False en vez de True. Este parámetro se establece en True por defecto.

Descarga de un archivo

Para descargar un archivo usando requests, podemos descargarlo transmitiendo el contenido o directamente descargando todo. los stream La bandera se usa para indicar ambos comportamientos.

Como probablemente adivinaste, si stream es True, luego requests transmitirá el contenido. Si stream es False, todo el contenido se descargará en la memoria antes de devolvérselo.

Para la transmisión de contenido, podemos iterar el contenido fragmento a fragmento utilizando el iter_content método o iterar línea por línea usando iter_line. De cualquier manera, descargará el archivo parte por parte.

Por ejemplo:

import requests

r = requests.get('https://cdn.pixabay.com/photo/2018/07/05/02/50/sun-hat-3517443_1280.jpg', stream=True)
downloaded_file = open("sun-hat.jpg", "wb")
for chunk in r.iter_content(chunk_size=256):
    if chunk:
        downloaded_file.write(chunk)

El código anterior descargará una imagen de Pixabay servidor y guárdelo en un archivo local, sun-hat.jpg.

También podemos leer datos sin procesar usando el raw propiedad y stream=True en la solicitud.

import requests

r = requests.get("http://exampleurl.com", stream=True)
r.raw

Para descargar o transmitir contenido, iter_content() es la forma preferida.

Errores y excepciones

requests arroja diferentes tipos de excepciones y errores si alguna vez hay un problema de red. Todas las excepciones se heredan de requests.exceptions.RequestException clase.

A continuación, se muestra una breve descripción de los errores comunes que puede encontrar:

  • ConnectionError se lanza una excepción en caso de DNS failure,refused connection o cualquier otro problema relacionado con la conexión.
  • Timeout se genera si se agota el tiempo de espera de una solicitud.
  • TooManyRedirects se genera si una solicitud supera el número máximo de redirecciones predefinidas.
  • HTTPError se genera una excepción para respuestas HTTP no válidas.

Para obtener una lista más completa y una descripción de las excepciones con las que puede encontrarse, consulte el documentación.

Conclusión

En este tutorial te expliqué muchas de las características del requests biblioteca y las diversas formas de utilizarla. Puedes usar requests biblioteca no solo para interactuar con una API REST, sino que también se puede usar para extraer datos de un sitio web o para descargar archivos de la web.

Modifique y pruebe los ejemplos anteriores y deje un comentario a continuación si tiene alguna pregunta sobre requests.

 

About the author

Ramiro de la Vega

Bienvenido a Pharos.sh

Soy Ramiro de la Vega, Estadounidense con raíces Españolas. Empecé a programar hace casi 20 años cuando era muy jovencito.

Espero que en mi web encuentres la inspiración y ayuda que necesitas para adentrarte en el fantástico mundo de la programación y conseguir tus objetivos por difíciles que sean.

Add comment

Sobre mi

Últimos Post

Etiquetas

Esta web utiliza cookies propias para su correcto funcionamiento. Al hacer clic en el botón Aceptar, aceptas el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Más información
Privacidad