Cómo utilizar cabeceras http con Axios para evitar la detección

Mihnea-Octavian Manolache el 27 de enero de 2023

blog-image

Las cabeceras HTTP son un aspecto importante de cualquier petición o respuesta HTTP, ya que permiten al cliente y al servidor intercambiar información adicional sobre la petición. Cuando se construye una aplicación web Node.js, es importante disponer de un cliente HTTP fiable y fácil de usar para realizar peticiones a APIs y otros servidores.

JavaScript y Node JS en particular ofrecen bastantes opciones cuando se trata de clientes HTTP. Sin embargo, uno de mis favoritos (y sin duda uno de los 5 mejores clientes HTTP de JavaScript) es Axios. Es por eso que hoy, nos centraremos en la configuración de cabeceras HTTP Axios.

Axios es una librería JavaScript ampliamente utilizada que simplifica el proceso de hacer peticiones HTTP y es especialmente útil cuando se trabaja con APIs en un entorno Node.js. En este artículo, vamos a explorar las diversas formas en que Axios se puede utilizar para trabajar con cabeceras HTTP. Al final del mismo, deberías ser capaz de entender:

  • ¿Qué es una cabecera HTTP y cómo funciona?
  • ¿Por qué Axios es un gran cliente HTTP para Javascript?
  • Cómo utilizar las cabeceras HTTP Axios en una aplicación web real

Cómo funciona la comunicación HTTP

Antes de entrar en la definición de una cabecera HTTP, creo que es importante tener al menos una idea general de cómo funciona el protocolo HTTP. Como seguro que ya sabes, el Protocolo de Transferencia de Hipertexto (HTTP) es la base sobre la que se construye la web hoy en día. A grandes rasgos, permite transferir información entre un servidor y sus clientes. El flujo real de este intercambio de información se parece a esto:

  1. El cliente abre una nueva conexión TCP
  2. Envía un mensaje al servidor, que se denomina solicitud HTTP
  3. El servidor recibe e interpreta la solicitud
  4. A continuación, envía un mensaje de vuelta al cliente, que se denomina respuesta HTTP
  5. El cliente lee el mensaje y continúa o cierra la conexión
blog-image

La parte importante en la que nos centraremos hoy es el mensaje, en particular el mensaje enviado por el cliente. Para que la comunicación entre el servidor y el cliente sea eficiente, los mensajes deben tener el formato descrito por el protocolo HTTP. Cuando se trata de la petición HTTP, los elementos que componen el mensaje son:

El método describe lo que queremos realizar con nuestra petición (si queremos recibir, enviar, actualizar información, etc.)

  • La ruta, la ubicación URL que estamos tratando de alcanzar
  • La versión del protocolo HTTP que estamos utilizando
  • Las cabeceras HTTP, que se utilizan para enviar información adicional y metadatos junto con nuestra solicitud.
  • El cuerpo, en caso de que estemos utilizando un método que envíe información al servidor (como una petición POST)

Qué son las cabeceras HTTP Axios y cómo funcionan

En pocas palabras, las cabeceras HTTP son campos que pasan información adicional y metadatos al mensaje. De nuevo, por mensaje entendemos la petición cuando la envía el cliente y la respuesta cuando la envía el servidor. Así que tanto el servidor como el cliente pueden pasar y recibir cabeceras. Por ejemplo, supongamos que quieres abrir una conexión persistente con el servidor. Por defecto, las conexiones HTTP se cierran después de cada petición. Para evitarlo, basta con pasar la cabecera `Keep-Alive`.

Cuando se trata de cabeceras HTTP con Axios, realmente no hay nada especial. Como hemos discutido, Axios es un cliente HTTP y ya hemos establecido que los clientes HTTP pueden enviar y recibir cabeceras.

Por qué Axios es un gran cliente HTTP para JavaScript

Ahora que ya sabemos cómo funciona HTTP, hablemos de "clientes". JavaScript ofrece unas cuantas opciones para 'interactuar programáticamente' con un servidor a través de HTTP. Entre las opciones más populares, están `axios`, `node-fetch` y `got`.

En la comunidad JavaScript hay diferentes opiniones sobre cuál utilizar. Por supuesto, hay muchos pros y contras para cada paquete, sin embargo, yo mismo elegí Axios después de realizar una simple prueba de velocidad entre los tres.

Aquí está el script que he utilizado para probar la velocidad:

// index.js

import { get_timing, array_sum } from './helpers.js'

import got from 'got'

import axios from 'axios'

const CALLS = 5

const send = async () => {

const res = {}



let start = process.hrtime()

await got('https://httpbin.org/')

const g = get_timing(start)

res.got = g

start = process.hrtime()

await axios.get('https://httpbin.org/')

const a = get_timing(start)

res.axios = a

start = process.hrtime()

await fetch('https://httpbin.org/')

const f = get_timing(start)

res.fetch = f

return res

}

let test_results = {

got: [],

axios: [],

fetch: []

}

let avg = {}

console.log(`[i] Process started with ${CALLS} iterations.`)

for (let i = 0; i<=CALLS; i++) {

let r = await send()

Object.entries(test_results).map(([key, value]) => test_results[key].push(r[key]))

}

Object.entries(test_results).forEach(([key, value]) => {

console.log(`\n[+] ${key}`)

console.log(` [i] Average: ${array_sum(value)/value.length}`)

console.log(` [i] Values: ${value}`)

avg[key] = array_sum(value)/value.length

}

)

console.log(`\n🚀🚀🚀 WINNER: ${Object.keys(avg).reduce((key, v) => avg[v] < avg[key] ? v : key)} [${CALLS} calls sent] 🚀🚀🚀`)

Y aquí están las funciones `helper`:

// helpers.js

export const get_timing = (start) => {

const NS_PER_SEC = 1e9

const NS_TO_MS = 1e6

const diff = process.hrtime(start)

return (diff[0] * NS_PER_SEC + diff[1]) / NS_TO_MS

}

export const array_sum = (array) => {

return array.reduce((accumulator, value) => {

return accumulator + value

}, 0)

}

He probado con 5, 10, 20 y 30 peticiones enviadas con cada paquete, 10 iteraciones cada vez y aquí está el resumen de los resultados:

blog-image

Por iteración, me refiero al número de ejecuciones del script, utilizando esta fórmula de bash, que genera un archivo .txt con los resultados de cada iteración:

~ " for i in {1..10}

do

node got.js > "${i}.txt"

echo "${i} done"

done

Como verás si consultas la tabla detallada de resultados, hay diferentes tiempos para cada lote y a veces Axios no es el más rápido. En general, sin embargo, Axios obtuvo una media de 387 milisegundos, medio segundo más rápido que sus oponentes. Got y Fetch tuvieron un tiempo de respuesta muy similar de aproximadamente 435 milisegundos de media. Dicho esto, si la velocidad es importante para tu proyecto, Axios es quizás el mejor cliente HTTP para ti.

Cómo enviar cabeceras HTTP con Axios

Personalmente, creo que aprender con la práctica da resultados casi instantáneos. Así que ahora que tenemos tanto el conocimiento como las herramientas para enviar cabeceras HTTP, empecemos a trabajar en un pequeño proyecto. En esta sección, configuraremos un nuevo proyecto Node, instalaremos Axios y lo usaremos para enviar cabeceras HTTP a un servidor.

Poner en marcha el proyecto

Antes de seguir adelante, asegúrese de que su máquina está equipada con:

Sugerencia: Puedes comprobar si tienes instalado Node JS escribiendo el siguiente comando en tu terminal:

~ " nodo -v 

v19.3.0

Ahora vamos a crear una nueva carpeta y abrirla en nuestro IDE. Si estás usando una máquina tipo UNIX (Mac o Linux), puedes crear programáticamente un nuevo directorio, desde tu terminal, escribiendo el siguiente comando:

~ " mkdir axios_project && cd axios_project 

~ " npm init -y

~ " npm i axios

~ " touch index.js

~ " code .

Estos comandos lo harán:

  1. Crea un nuevo directorio (llamado 'axios_project') y navega hasta él
  2. Inicializar un nuevo proyecto Node JS dentro del directorio
  3. Instala `axios` dentro de tu proyecto
  4. Crear un nuevo archivo 'index.js
  5. Abra su IDE en el proyecto actual

Código para aprender

En realidad hay varias formas de enviar cabeceras HTTP con Axios. Por ejemplo, puedes usar un objeto config como se describe aquí, o puedes usar los métodos de instancia, que fusionarán automáticamente la configuración que pases con la configuración de instancia. También puedes usar el objeto `axios.defaults.headers.common` para establecer cabeceras por defecto para todas las peticiones Axios.

Además, ten en cuenta que Axios es un cliente HTTP basado en promesas. Esto significa que tendremos que esperarla dentro de una función asíncrona, o resolver la respuesta.

Con estos dos aspectos en mente, comencemos con la codificación. Trabajaremos dentro del archivo 'index.js'. Para mayor comodidad, vamos a recapitular lo que tenemos que hacer de antemano:

  1. Importar `axios` dentro de nuestro archivo
  2. Definir un objeto config que contendrá nuestras cabeceras
  3. Pasar la configuración a `axios` para hacer una petición
  4. Imprimir la respuesta dentro de nuestro terminal

#1: Enviar una petición GET utilizando el objeto config

import axios from "axios"

const config = {

method: 'GET',

url: 'https://httpbin.org/headers',

headers: {

'HTTP-Axios-Headers': 'This is my custom header.'

}

}

axios(config)

.then((response) => {

console.log(response)

})

.catch((err) => {

console.log(err)

})

Enviar cabeceras HTTP con Axios es de lo más sencillo. Para ejecutar este script, simplemente ejecute el siguiente comando dentro de su terminal:

~ » node index.js  

{

status: 200,

statusText: 'OK',

headers: ...,

config: ...,

request: ...,

data: {

headers: {

'Accept': 'application/json, text/plain, */*',

'Accept-Encoding': 'gzip, compress, deflate, br',

'Host': 'httpbin.org',

'Http-Axios-Headers': 'This is my custom header.',

'User-Agent': 'axios/1.2.2',

'X-Amzn-Trace-Id': 'Root=1-63b54d94-7656f02113483dfa036c476c'

}

}

}

La respuesta completa es bastante grande y sigue este esquema. Sin embargo, lo que más nos interesa es el `data`, que contiene la respuesta real que recibimos del servidor. Ahora mira la respuesta de arriba. Recuerda que enviamos una cabecera personalizada `Http-Axios-Headers` al servidor y, como puedes ver, el servidor la recibió.

#2: Enviar una petición POST utilizando el método alias

import axios from "axios"

const data = {

'foo':'bar'

}

const config = {

headers: {

'HTTP-Axios-Headers': 'This is my custom header.'

}

}

axios.post('http://httpbin.org/post', data, config)

.then(response => console.log(response.data))

.catch(err => console.log(err))

Observa cómo para enviar una petición POST, he añadido un nuevo objeto `data` a nuestro script y también he cambiado la URL. Ahora, si ejecutas el script, verás que estos son los datos recibidos del servidor:

{

args: {},

data: '{"foo":"bar"}',

files: {},

form: {},

headers: {

Accept: 'application/json, text/plain, */*',

'Accept-Encoding': 'gzip, compress, deflate, br',

'Content-Length': '13',

'Content-Type': 'application/json',

Host: 'httpbin.org',

'Http-Axios-Headers': 'This is my custom header.',

'User-Agent': 'axios/1.2.2',

'X-Amzn-Trace-Id': 'Root=1-63b5508a-3a86493f087662d3169e80ee'

},

json: { foo: 'bar' },

origin: '49.12.221.20',

url: 'http://httpbin.org/post'

}

Cómo utilizar cabeceras HTTP en Axios para el Web Scraping

Si estás planeando utilizar Axios para el web scraping, ten en cuenta que la mayoría de los sitios web tienen reglas de protección que bloquean las solicitudes procedentes de software automatizado (incluidos los web scrapers).

El uso de cabeceras HTTP, en particular la cabecera `User-Agent`, puede ser una técnica útil para evitar ser detectado cuando se realiza web scraping. La cabecera User-Agent identifica el navegador y el sistema operativo del cliente ante el servidor, y los servidores web pueden servir contenidos diferentes o bloquear peticiones basándose en esta información. Configurando la cabecera User-Agent puedes imitar un navegador web común, aumentando así tus posibilidades de eludir algunos mecanismos de detección.

A continuación se muestra un ejemplo de cómo utilizar el encabezado User-Agent con Axios para evitar ser detectado al hacer web scraping:

import axios from "axios"

axios.defaults.headers.common['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'

axios({

method: 'GET',

url: 'https://httpbin.org/get',

}).then(response => {

console.log(response.data)

});

Esta vez he utilizado la opción de configuración predeterminada de Axios, que aplica el encabezado a todas las solicitudes futuras. En este ejemplo, la cabecera User-Agent está configurada para imitar al navegador Chrome en un sistema operativo Windows 10. Puede que quieras probar a utilizar diferentes valores de User-Agent o una variedad de cabeceras diferentes para ver qué funciona mejor para tu caso de uso específico.

Vale la pena señalar que, aunque cambiar el encabezado User-Agent puede ayudarle a evitar la detección en algunos casos, no es un método infalible, y los servidores web pueden seguir siendo capaces de identificar que está utilizando un raspador web. Por lo tanto, es una buena idea utilizar una combinación de técnicas para evitar la detección y permanecer dentro de los límites de los términos de servicio del sitio web.

Conclusiones

Usar cabeceras HTTP con Axios (o con cualquier otro cliente HTTP) puede aumentar la eficiencia de la comunicación entre un servidor y un cliente. Además, puede incluso ayudarte a evitar ser detectado cuando estás construyendo un web scraper. De hecho, en WebScrapingAPI utilizamos varios agentes de usuario como una de las técnicas básicas de evasión.

Por supuesto, la detección no se limita a los agentes de usuario, pero es un buen punto de partida. Aquí tienes un buen tutorial sobre cómo evitar que baneen tu dirección IP cuando haces web scraping que te ayudará a entender mejor cómo funcionan las evasiones.

Mientras tanto, ¿sabías que Web Scraping API te permite establecer cabeceras personalizadas a tu petición? Si no es así, obtén más información aquí.

Noticias y actualidad

Manténgase al día de las últimas guías y noticias sobre raspado web suscribiéndose a nuestro boletín.

We care about the protection of your data. Read our <l>Privacy Policy</l>.Privacy Policy.

Artículos relacionados

miniatura
GuíasGuía de inicio rápido de la API de Web Scraping

Empiece con WebScrapingAPI, la solución definitiva para el web scraping. Recopile datos en tiempo real, evite los sistemas anti-bot y disfrute de soporte profesional.

Mihnea-Octavian Manolache
avatar de autor
Mihnea-Octavian Manolache
9 min leer
miniatura
GuíasDesbloquea sitios web y protege tu identidad con proxies y Axios Node.js

Aprende a usar proxies con Axios y Node.js para un raspado web eficiente. Consejos, ejemplos de código y los beneficios de usar WebScrapingAPI incluidos.

Suciu Dan
avatar de autor
Suciu Dan
7 min leer
miniatura
GuíasDescubre cómo scrapear tablas HTML con Golang

Aprenda a raspar tablas HTML con Golang para una potente extracción de datos. Explore la estructura de las tablas HTML y construya un raspador web utilizando la simplicidad, la concurrencia y la robusta biblioteca estándar de Golang.

Andrei Ogiolan
avatar de autor
Andrei Ogiolan
8 min leer