Introducción
Contenido
- 1 Introducción
- 2 Instalación del módulo de solicitudes
- 3 Hacer una solicitud GET
- 4 Leer la respuesta
- 5 Pasar parámetros en GET
- 6 Realización de solicitudes POST
- 7 Envío de archivos con POST
- 8 Otros tipos de solicitudes HTTP
- 9 Manejo de redirecciones
- 10 Manejo de tiempos de espera
- 11 Cookies y encabezados personalizados
- 12 El objeto de sesión
- 13 Usando Proxies
- 14 Manejo SSL
- 15 Descarga de un archivo
- 16 Errores y excepciones
- 17 Conclusió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.
Te puede interesar:Minería de reglas de asociación a través del algoritmo Apriori en Python- 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.
Te puede interesar:Usando Regex para la manipulación de texto en PythonEn 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:
Te puede interesar:Implementando LDA en Python con Scikit-Learn{"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 deDNS 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
.
Te puede interesar:Crear y eliminar directorios con Python