En esta guía, recorreremos los siguientes conceptos de uso de API con Python:
- ¿Qué es HTTP?
- ¿Qué es una API REST?
- Cómo realizar una solicitud GET
- Cómo realizar una solicitud POST
- Cómo utilizar un SDK
¿Qué es HTTP?
HTTP (Protocolo de transferencia de hipertexto) es el estándar para la mayoría de los datos que viajan por la web. Probablemente hayas oído que las bases de datos constituyen el backend de la mayoría de los sitios web, y esto es cierto, pero hay matices en la forma en que nuestro cliente (navegador o script de Python) interactúa realmente con la base de datos. HTTP es la capa de comunicación entre el cliente y el servidor backend.
Cuando se utiliza HTTP para el scraping y las APIs web, estos son los métodos que es más probable que utilice.
- GET: El método más utilizado con diferencia. Cada vez que visita un sitio, su navegador realiza un GET para el HTML y, a continuación, representa la página para que usted la vea.
- POST: Este es el segundo método más común. POST se utiliza para transferir grandes volúmenes de datos de forma segura, y más a menudo para añadir algo a una base de datos. Cuando rellenas formularios y encuestas o publicas en redes sociales, estás realizando una solicitud POST.
- PUT: Las solicitudes PUT se utilizan para actualizar elementos existentes en una base de datos. Cuando editas una publicación en una red social, se utiliza PUT.
- DELETE: Si desea eliminar una publicación en una red social (o cualquier otra cosa de una base de datos), su navegador envía una solicitud DELETE al servidor para eliminarla.
HTTP y su falta de normas de retorno
A pesar de su simplicidad, HTTP carece de un estándar de retorno universal. Algunos servidores devuelven HTML por defecto, mientras que otros escupen JSON o incluso estructuras de datos heredadas como XML y texto plano.
Primero, hagamos una petición GET básica. Si aún no tienes instalado Python Requests, puedes instalarlo a través de pip.
pip install requests
Una vez que tengas Requests instalado, puedes ejecutar el siguiente código para hacer un simple GET. Presta atención a la salida del terminal.
import requests
response = requests.get("https://quotes.toscrape.com")
print(response.text)
Después de ejecutar el código, deberías notar que tenemos una página HTML. Esto es genial para ver en el navegador, pero en el terminal, es bastante feo. La salida de abajo se ha recortado, pero usted consigue la idea.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Quotes to Scrape</title>
<link rel="stylesheet" href="/static/bootstrap.min.css">
<link rel="stylesheet" href="/static/main.css">
</head>
<body>
<div class="container">
<div class="row header-box">
<div class="col-md-8">
<h1>
<a href="/" style="text-decoration: none">Quotes to Scrape</a>
</h1>
</div>
<div class="col-md-4">
<p>
<a href="/login">Login</a>
</p>
</div>
</div>
<div class="row">
<div class="col-md-8">
<div class="quote" itemscope itemtype="http://schema.org/CreativeWork">
<span class="text" itemprop="text">“The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.”</span>
<span>by <small class="author" itemprop="author">Albert Einstein</small>
<a href="/author/Albert-Einstein">(about)</a>
</span>
<div class="tags">
Tags:
<meta class="keywords" itemprop="keywords" content="change,deep-thoughts,thinking,world" / >
<a class="tag" href="/tag/change/page/1/">change</a>
<a class="tag" href="/tag/deep-thoughts/page/1/">deep-thoughts</a>
<a class="tag" href="/tag/thinking/page/1/">thinking</a>
<a class="tag" href="/tag/world/page/1/">world</a>
</div>
</div>
<div class="quote" itemscope itemtype="http://schema.org/CreativeWork">
<span class="text" itemprop="text">“It is our choices, Harry, that show what we truly are, far more than our abilities.”</span>
<span>by <small class="author" itemprop="author">J.K. Rowling</small>
<a href="/author/J-K-Rowling">(about)</a>
</span>
<div class="tags">
Tags:
<meta class="keywords" itemprop="keywords" content="abilities,choices" / >
<a class="tag" href="/tag/abilities/page/1/">abilities</a>
<a class="tag" href="/tag/choices/page/1/">choices</a>
</div>
</div>
Las páginas HTML están pensadas para ser leídas y renderizadas por los navegadores. No están diseñadas para que usted las lea o las integre en su código.
Cómo REST (Representational State Transfer) soluciona esto
Las API REST nos proporcionan un estándar de diseño para las canalizaciones de datos. JSON es, con diferencia, el tipo de retorno más popular de las API REST. Es flexible y fácil de leer. Esta sintaxis clara y legible también hace que sea fácil de analizar desde su entorno de programación.
Eche un vistazo a continuación para ver el aspecto real de JSON. Recuerda que utilizamos una API REST para obtener este tipo de estructura de datos.
{
"name": "Jake",
"age": 34,
"professions": ["writing", "coding"]
}
Las API REST utilizan puntos finales, parámetros y métodos HTTP para controlar los datos devueltos y su formato.
Realización de la primera solicitud de API
Ahora que ya sabes lo que se supone que debe hacer una API REST, vamos a intentar utilizar una. Quotes to Scrape también tiene una API REST. En lugar de simplemente obtener la página de inicio, ahora vamos a acceder a su API. Nos estamos comunicando con el servidor a través de endpoints.
Nuestro endpoint completo /api/quotes
puede dividirse en dos partes.
/api
: Esto le dice al servidor que queremos datos estructurados de la API, no páginas HTML./quotes
: Queremos que la API devuelva datos del endpointquotes
.
Hacer la solicitud
Sigue adelante y ejecuta el código como lo hiciste antes.
import requests
import json
response = requests.get("https://quotes.toscrape.com/api/quotes")
print(json.dumps(response.json(), indent=4))
Ahora nuestros datos están limpios y estructurados. Son fáciles de analizar y, a partir de ahí, podemos hacer prácticamente cualquier cosa con ellos.
{
"has_next": true,
"page": 1,
"quotes": [
{
"author": {
"goodreads_link": "/author/show/9810.Albert_Einstein",
"name": "Albert Einstein",
"slug": "Albert-Einstein"
},
"tags": [
"change",
"deep-thoughts",
"thinking",
"world"
],
"text": "\u201cThe world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.\u201d"
},
{
"author": {
"goodreads_link": "/author/show/1077326.J_K_Rowling",
"name": "J.K. Rowling",
"slug": "J-K-Rowling"
},
"tags": [
"abilities",
"choices"
],
"text": "\u201cIt is our choices, Harry, that show what we truly are, far more than our abilities.\u201d"
},
{
"author": {
"goodreads_link": "/author/show/9810.Albert_Einstein",
"name": "Albert Einstein",
"slug": "Albert-Einstein"
},
"tags": [
"inspirational",
"life",
"live",
"miracle",
"miracles"
],
"text": "\u201cThere are only two ways to live your life. One is as though nothing is a miracle. The other is as though everything is a miracle.\u201d"
},
{
"author": {
"goodreads_link": "/author/show/1265.Jane_Austen",
"name": "Jane Austen",
"slug": "Jane-Austen"
},
"tags": [
"aliteracy",
"books",
"classic",
"humor"
],
"text": "\u201cThe person, be it gentleman or lady, who has not pleasure in a good novel, must be intolerably stupid.\u201d"
},
{
"author": {
"goodreads_link": "/author/show/82952.Marilyn_Monroe",
"name": "Marilyn Monroe",
"slug": "Marilyn-Monroe"
},
"tags": [
"be-yourself",
"inspirational"
],
"text": "\u201cImperfection is beauty, madness is genius and it's better to be absolutely ridiculous than absolutely boring.\u201d"
},
{
"author": {
"goodreads_link": "/author/show/9810.Albert_Einstein",
"name": "Albert Einstein",
"slug": "Albert-Einstein"
},
"tags": [
"adulthood",
"success",
"value"
],
"text": "\u201cTry not to become a man of success. Rather become a man of value.\u201d"
},
{
"author": {
"goodreads_link": "/author/show/7617.Andr_Gide",
"name": "Andr\u00e9 Gide",
"slug": "Andre-Gide"
},
"tags": [
"life",
"love"
],
"text": "\u201cIt is better to be hated for what you are than to be loved for what you are not.\u201d"
},
{
"author": {
"goodreads_link": "/author/show/3091287.Thomas_A_Edison",
"name": "Thomas A. Edison",
"slug": "Thomas-A-Edison"
},
"tags": [
"edison",
"failure",
"inspirational",
"paraphrased"
],
"text": "\u201cI have not failed. I've just found 10,000 ways that won't work.\u201d"
},
{
"author": {
"goodreads_link": "/author/show/44566.Eleanor_Roosevelt",
"name": "Eleanor Roosevelt",
"slug": "Eleanor-Roosevelt"
},
"tags": [
"misattributed-eleanor-roosevelt"
],
"text": "\u201cA woman is like a tea bag; you never know how strong it is until it's in hot water.\u201d"
},
{
"author": {
"goodreads_link": "/author/show/7103.Steve_Martin",
"name": "Steve Martin",
"slug": "Steve-Martin"
},
"tags": [
"humor",
"obvious",
"simile"
],
"text": "\u201cA day without sunshine is like, you know, night.\u201d"
}
],
"tag": null,
"top_ten_tags": [
[
"love",
14
],
[
"inspirational",
13
],
[
"life",
13
],
[
"humor",
12
],
[
"books",
11
],
[
"reading",
7
],
[
"friendship",
5
],
[
"friends",
4
],
[
"truth",
4
],
[
"simile",
3
]
]
}
Realizar una solicitud autenticada
Ahora que hemos visto cómo solicitar datos públicos, veamos las API autenticadas. En muchos casos, necesitará una clave de API para obtener los datos. La mayoría de los servidores de API requieren un encabezado de autorización
con su clave de API para autenticar su solicitud.
Hacer una petición GET básica es bastante fácil. Ahora, intentaremos hacer una petición POST. Las peticiones POST se utilizan para manejar cargas más grandes de información de forma segura. En el código siguiente, utilizamos la API Web Unlocker para analizar la página y devolver markdown.
import requests
API_KEY = "your-api-key"
ZONE = "web_unlocker1"
url = "https://api.brightdata.com/request"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
payload = {
"url": "https://quotes.toscrape.com/",
"zone": ZONE,
"format": "raw",
"data_format": "markdown"
}
response = requests.post(url, headers=headers, json=payload)
print(response.text)
Esta vez, nuestra petición va a https://api.brightdata.com/request.
Todo está controlado por nuestras cabeceras
y carga útil
.
Aquí están nuestras cabeceras
:
- “
Authorization": f "Portador {API_KEY}"
: Esto vincula la solicitud a su cuenta de Bright Data. "Content-Type": "application/json
“: Esto le dice al servidor que estamos enviando datos en formato JSON.
Ahora, echa un vistazo a la carga útil
:
"url"
: La url a la que queremos acceder con Web Unlocker."zone"
: El nombre de zona que le dio a su instancia de Web Unlocker."formato"
: El formato de respuesta que queremos (en este caso raw).- “
formato_datos"
: Usamos “markdown”-esto le dice a Bright Data que queremos la página analizada en formato markdown. No es tan flexible como JSON, pero se puede convertir a JSON fácilmente.
Aquí está la salida del terminal ahora que la página se ha convertido a markdown.
# [Quotes to Scrape](/)
[Login](/login)
“The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.” by Albert Einstein [(about)](/author/Albert-Einstein)
Tags: [change](/tag/change/page/1/) [deep-thoughts](/tag/deep-thoughts/page/1/) [thinking](/tag/thinking/page/1/) [world](/tag/world/page/1/)
“It is our choices, Harry, that show what we truly are, far more than our abilities.” by J.K. Rowling [(about)](/author/J-K-Rowling)
Tags: [abilities](/tag/abilities/page/1/) [choices](/tag/choices/page/1/)
“There are only two ways to live your life. One is as though nothing is a miracle. The other is as though everything is a miracle.” by Albert Einstein [(about)](/author/Albert-Einstein)
Tags: [inspirational](/tag/inspirational/page/1/) [life](/tag/life/page/1/) [live](/tag/live/page/1/) [miracle](/tag/miracle/page/1/) [miracles](/tag/miracles/page/1/)
“The person, be it gentleman or lady, who has not pleasure in a good novel, must be intolerably stupid.” by Jane Austen [(about)](/author/Jane-Austen)
Tags: [aliteracy](/tag/aliteracy/page/1/) [books](/tag/books/page/1/) [classic](/tag/classic/page/1/) [humor](/tag/humor/page/1/)
“Imperfection is beauty, madness is genius and it's better to be absolutely ridiculous than absolutely boring.” by Marilyn Monroe [(about)](/author/Marilyn-Monroe)
Tags: [be-yourself](/tag/be-yourself/page/1/) [inspirational](/tag/inspirational/page/1/)
“Try not to become a man of success. Rather become a man of value.” by Albert Einstein [(about)](/author/Albert-Einstein)
Tags: [adulthood](/tag/adulthood/page/1/) [success](/tag/success/page/1/) [value](/tag/value/page/1/)
“It is better to be hated for what you are than to be loved for what you are not.” by André Gide [(about)](/author/Andre-Gide)
Tags: [life](/tag/life/page/1/) [love](/tag/love/page/1/)
“I have not failed. I've just found 10,000 ways that won't work.” by Thomas A. Edison [(about)](/author/Thomas-A-Edison)
Tags: [edison](/tag/edison/page/1/) [failure](/tag/failure/page/1/) [inspirational](/tag/inspirational/page/1/) [paraphrased](/tag/paraphrased/page/1/)
“A woman is like a tea bag; you never know how strong it is until it's in hot water.” by Eleanor Roosevelt [(about)](/author/Eleanor-Roosevelt)
Tags: [misattributed-eleanor-roosevelt](/tag/misattributed-eleanor-roosevelt/page/1/)
“A day without sunshine is like, you know, night.” by Steve Martin [(about)](/author/Steve-Martin)
Tags: [humor](/tag/humor/page/1/) [obvious](/tag/obvious/page/1/) [simile](/tag/simile/page/1/)
* [Next →](/page/2/)
## Top Ten tags
[love](/tag/love/) [inspirational](/tag/inspirational/) [life](/tag/life/) [humor](/tag/humor/) [books](/tag/books/) [reading](/tag/reading/) [friendship](/tag/friendship/) [friends](/tag/friends/) [truth](/tag/truth/) [simile](/tag/simile/)
Quotes by: [GoodReads.com](https://www.goodreads.com/quotes)
M
La autenticación utiliza un identificador único, normalmente una clave API. En este caso, hemos obtenido acceso a Web Unlocker, pero el principio es el mismo, independientemente del servicio de API que utilices.
Gestión de la respuesta
Cada respuesta incluye un código de estado. Los códigos de estado se utilizan para transmitir diferentes mensajes al cliente. En un mundo perfecto, siempre recibirás un estado 200
.
Por desgracia, el mundo no es perfecto. Si recibes un código no-200, significa que algo va mal.
- 400-499: Estos códigos suelen implicar un error en el lado del cliente. Compruebe su clave API y el formato de la solicitud.
- 500-599: Este rango indica un error del servidor. Tu solicitud estaba bien, pero el servidor no pudo completarla por una razón u otra.
Puedes aprender más sobre códigos de estado aquí. Si quieres aprender a manejar estos códigos de estado desde Python, echa un vistazo a esta guía sobre lógica de reintentos.
Un SDK permite prescindir de la “boilerplate
Un SDK (kit de desarrollo de software) nos permite conectarnos a una API REST sin tener que escribir código para la gestión de errores y la lógica de reintento. La API OpenAI también ofrece una API REST completa. Puedes echarle un vistazo aquí.
Para instalar su SDK y omitir las peticiones HTTP, ejecute el siguiente comando.
pip install openai
Ahora, importamos el SDK de OpenAI. Obtenemos la página HTML como lo hicimos inicialmente. Si estás interesado en parsear HTML manualmente, puedes aprender cómo usar Requests con BeautifulSoup. Una vez que hemos recuperado la página HTML, usamos el SDK para pasar la página a ChatGPT para su análisis.
from openai import OpenAI
import requests
OPENAI_API_KEY = "sk-your-openai-api-key"
response = requests.get("https://quotes.toscrape.com")
html_page = response.text
client = OpenAI(api_key=OPENAI_API_KEY)
chat = client.chat.completions.create(
messages=[
{
"role": "user",
"content": f"Parse the quotes from the following page. I want JSON only--zero commentary from you, here's the page: {html_page}",
}
],
model="gpt-4o-mini",
)
reply = chat.choices[0].message.content
print(f"ChatGPT: {reply}")
Echa un vistazo a la salida esta vez. No es necesario analizar nada, sólo los datos dentro de un bloque json.
[
{
"text": "The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.",
"author": "Albert Einstein",
"tags": ["change", "deep-thoughts", "thinking", "world"]
},
{
"text": "It is our choices, Harry, that show what we truly are, far more than our abilities.",
"author": "J.K. Rowling",
"tags": ["abilities", "choices"]
},
{
"text": "There are only two ways to live your life. One is as though nothing is a miracle. The other is as though everything is a miracle.",
"author": "Albert Einstein",
"tags": ["inspirational", "life", "live", "miracle", "miracles"]
},
{
"text": "The person, be it gentleman or lady, who has not pleasure in a good novel, must be intolerably stupid.",
"author": "Jane Austen",
"tags": ["aliteracy", "books", "classic", "humor"]
},
{
"text": "Imperfection is beauty, madness is genius and it's better to be absolutely ridiculous than absolutely boring.",
"author": "Marilyn Monroe",
"tags": ["be-yourself", "inspirational"]
},
{
"text": "Try not to become a man of success. Rather become a man of value.",
"author": "Albert Einstein",
"tags": ["adulthood", "success", "value"]
},
{
"text": "It is better to be hated for what you are than to be loved for what you are not.",
"author": "André Gide",
"tags": ["life", "love"]
},
{
"text": "I have not failed. I've just found 10,000 ways that won't work.",
"author": "Thomas A. Edison",
"tags": ["edison", "failure", "inspirational", "paraphrased"]
},
{
"text": "A woman is like a tea bag; you never know how strong it is until it's in hot water.",
"author": "Eleanor Roosevelt",
"tags": ["misattributed-eleanor-roosevelt"]
},
{
"text": "A day without sunshine is like, you know, night.",
"author": "Steve Martin",
"tags": ["humor", "obvious", "simile"]
}
]
Los SDK le ofrecen toda la potencia de una API REST sin necesidad de gestionar HTTP manualmente. Si te interesa aprender a hacer scraping con IA, echa un vistazo a nuestras guías para Claude y DeepSeek.
Conclusión
Ahora que ya sabes cómo hacer peticiones API básicas con Python, puedes pasar a proyectos más grandes. Puedes usar APIs para interactuar con varios servicios para recuperar datos e incluso puedes utilizar un SDK para analizar automáticamente esos datos. En este tutorial, utilizamos Web Unlocker, pero Bright Data ofrece una variedad de otros productos para ayudarle con sus necesidades de datos.
- Proxies residenciales: Dirija su tráfico HTTP a través de dispositivos reales con direcciones IP residenciales.
- API de raspado: Automatiza completamente tu scrape y descarga los resultados directamente a tu entorno de programación.
- Navegador de raspado: Evita CAPTCHAs y controla un navegador real desde tu script Python.
Solicite una prueba gratuita y empiece hoy mismo.
No se requiere tarjeta de crédito