El m贸dulo de solicitudes de Python

    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.

     

    Etiquetas:

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *