Volver al blog
La ciencia del web scraping
Sorin-Gabriel MaricaLast updated on Mar 31, 20268 min read

Desbloqueador de nodos para el rastreo web

Desbloqueador de nodos para el rastreo web

A todos nos fastidia cuando intentamos acceder a una página y el sitio bloquea nuestra solicitud sin motivo aparente. El bloqueo geográfico, por ejemplo, solo se puede eludir utilizando un proxy. 

Node-unblocker nos ayuda a crear un proxy personalizado y a tenerlo listo y funcionando en cuestión de minutos.

¿Qué es Node-Unblocker?

Node-unblocker es una biblioteca de uso general para crear un proxy web, interceptar y modificar solicitudes y respuestas. 

Esta biblioteca también se utiliza en el web scraping para eludir restricciones implementadas por el sitio, como el geobloqueo, ocultar la dirección IP y limitar la velocidad, o para enviar tokens de autenticación. 

En resumen, al utilizar esta biblioteca, puedes decir adiós al contenido bloqueado y censurado.

En este artículo, crearemos una aplicación Express con un proxy personalizado utilizando Node Unblocker, añadiremos un middleware que cambie el agente de usuario para cada solicitud, analizaremos las limitaciones del proxy, lo implementaremos en Heroku y lo compararemos con un servicio gestionado como WebScrapingAPI.

Requisitos previos

Antes de empezar, asegúrate de tener instalada la última versión de Node.JS. La instalación de Node.JS para cada plataforma (Windows, Linux, Mac) sería tema de un artículo aparte, así que, en lugar de entrar en detalles, consulta la página web oficial y sigue las instrucciones.

Configuración

Empezamos creando un directorio para nuestro proyecto llamado unblocked e inicializamos un proyecto de Node.JS dentro de él:

mkdir unblocked
cd unblocked
npm init

Instalación de dependencias

Para esta aplicación, instalamos dos bibliotecas: Express, un marco minimalista para Node.JS, y Node Unblocker.

npm install express unblocker

Crear la aplicación base

Creación de la aplicación Express

Dado que node.unblocker se ejecuta dentro de una instancia de Express, tenemos que configurar el ejemplo «Hello World» en nuestra aplicación.

Crea un archivo index.js y pega el siguiente código:

const express = require('express') const app = express() const port = 8080 app.get('/', (req, res) => { res.send('Hello World!') }) app.listen(process.env.PORT || 8080, () => { console.log(`Example app listening on port ${port}`) })

Podemos ejecutar la aplicación con este comando:

node index.js

Si accedemos a http://localhost:8080, veremos un mensaje de «Hello World». Esto significa que nuestra aplicación está en funcionamiento.

Añadir Node Unblocker a Express

Es hora de importar la biblioteca Node Unblock a nuestra aplicación:

var Unblocker = require('unblocker')

Creamos una instancia de Node Unblocker y le pasamos el parámetro proxy. Puedes encontrar la lista completa de parámetros disponibles aquí.

var unblocker = new Unblocker({prefix: '/proxy/'})

Registramos la biblioteca Node Unblocker en Express como middleware para que se intercepten las solicitudes:

app.use(unblocker)

Actualizamos el listener de la aplicación Express para añadir compatibilidad con websockets:

app.listen(process.env.PORT || 8080, () => { console.log(`Example app listening on port ${port}`) }).on('upgrade', unblocker.onUpgrade)

Tras seguir todos estos pasos, nuestra aplicación debería tener este aspecto:

const express = require('express') const Unblocker = require('unblocker') const app = express() const port = 8080 const unblocker = new Unblocker({prefix: '/proxy/'}) app.use(unblocker) app.get('/', (req, res) => { res.send('Hello World!') }) app.listen(process.env.PORT || 8080, () => { console.log(`Example app listening on port ${port}`) }).on('upgrade', unblocker.onUpgrade)

Probar el proxy

Reinicia la aplicación y accede a la siguiente URL en tu navegador:

http://localhost:8080/proxy/https://webscrapingapi.com

Para asegurarnos de que el proxy funciona como se espera, abrimos las Herramientas de desarrollador en el navegador y comprobamos la pestaña Red. Todas las solicitudes deberían pasar por el proxy.

Para cualquier problema que pueda presentar el proxy, se recomienda habilitar el modo de depuración configurando la variable de entorno DEBUG. Utiliza este comando para iniciar el proxy en modo de depuración:

DEBUG=unblocker:* node index.js

Nunca es buena idea habilitar esto en producción, así que reservémoslo solo para el entorno de desarrollo.

Uso de middlewares

Nodeunblocker no es solo una solución de proxy personalizada, sino que permite la interceptación y modificación de las solicitudes entrantes y salientes a través de middleware.

Podemos utilizar esta función para bloquear la carga de recursos específicos en función del tipo de recurso o del dominio, actualizar el agente de usuario, sustituir el contenido devuelto o inyectar tokens de autenticación en los encabezados de las solicitudes.

Puedes encontrar una lista completa de ejemplos aquí.

Empecemos creando un middleware para configurar un agente de usuario personalizado. Crea un archivo llamado user-agent.js y añade este código:

module.exports = function(userAgent) {
    function setUserAgent(data) {
        data["headers"]["user-agent"] = userAgent
    }
    return setUserAgent
}

Esta función acepta el agente de usuario personalizado con el parámetro userAgent y lo registra en el objeto data utilizando la función setUserAgent. Node unblocked llamará a la función setUserAgent con cada solicitud.

const userAgent = require('./user-agent')

Configuramos el parámetro requestMiddleware en el constructor de Unblocker y ya deberíamos estar listos.

const unblocker = new Unblocker({
    prefix: '/proxy/',
    requestMiddleware: [userAgent("nodeunblocker/1.5")]
})

Nuestro archivo index.js debería tener este aspecto:

const express = require('express')
const Unblocker = require('unblocker')
const userAgent = require('./user-agent')
const app = express()
const port = 8080

const unblocker = new Unblocker({
    prefix: '/proxy/',
    requestMiddleware: [userAgent("nodeunblocker/1.5")]
})

app.use(unblocker)

app.get('/', (req, res) => {
    res.send('Hello World!')
})

app.listen(process.env.PORT || 8080, () => {
    console.log(`Example app listening on port ${port}`)
}).on('upgrade', unblocker.onUpgrade)

Es hora de comprobar si nuestro código funciona. Tenemos que cambiar la URL de node-unblocker para asegurarnos de que los encabezados se actualizan correctamente. 

Reinicia la aplicación y abre esta URL en tu navegador:

http://localhost:8080/proxy/https://www.whatsmyua.info/

Si el sitio muestra nodeunblocker/1.5, nuestro middleware funciona.

Implementación en Heroku

Con nuestro proxy en funcionamiento, es hora de implementarlo en Heroku, una plataforma como servicio (PaaS) que nos permite crear, lanzar y gestionar aplicaciones íntegramente en la nube.

Ten en cuenta que no todos los proveedores permiten proxies y aplicaciones de web scraping en su infraestructura. Heroku acepta este tipo de aplicaciones siempre y cuando no se ignoren las reglas de robots.txt.

Una vez aclarada la parte legal, preparemos nuestro proyecto para la implementación.

Script y motor

Tenemos que configurar el script de inicio y los motores en el archivo package.json.

La propiedad `engines` le indica a Heroku que necesitamos la última versión de Node.JS 16 instalada en nuestro entorno. El script de inicio se ejecuta cuando el entorno está configurado y nuestra aplicación está lista para ejecutarse.

Nuestro package.json debería tener este aspecto:

{
  "name": "unblocked",
  "version": "1.0.0",
  "main": "index.js",
  "engines": {
    "node": "16.x"
  },
  "scripts": {
    "start": "node index.js"
  },
  "dependencies": {
    "express": "^4.18.1",
    "unblocker": "^2.3.0"
  }
}

Heroku ha convertido la implementación de una aplicación Node.JS en un placer. Antes de pasar a la siguiente sección, asegúrate de haber instalado la CLI de Heroku y las herramientas de Git.

Inicio de sesión y configuración

Utiliza este comando para autenticarte en Heroku desde tu terminal local:

heroku login

Crea una nueva aplicación de Heroku ejecutando este comando:

heroku apps:create

Este comando devolverá el ID de la aplicación y un repositorio de Git. Usemos el ID para configurar el origen remoto de nuestro repositorio:

git init
heroku git:remote -a [YOUR_APP_ID]

Dado que nunca es buena idea incluir la carpeta node_modules en el control de versiones, vamos a crear un archivo .gitignore y añadir la carpeta a él.

Implementación

El último paso antes de que nuestro código llegue a producción es confirmarlo e implementarlo. Añadamos todos los archivos, creemos una confirmación y fusionemos la rama maestra con la de Heroku.

git add .
git commit -am "Initial commit"
git push heroku master

Tras unos segundos, la aplicación se implementará en Heroku. ¡Enhorabuena! Es hora de acceder a ella en nuestro navegador y asegurarnos de que funciona.

Utiliza la siguiente estructura de URL para crear la URL de Heroku:

[HEROKU_DYNO_URL]/proxy/https://webscrapingapi.com

Si has olvidado o perdido la URL de Dyno, puedes utilizar este comando para obtener la información disponible sobre la aplicación actual:

heroku info

Limitaciones

La facilidad de configuración de este proxy personalizado tiene una salvedad: solo funciona bien para sitios web sencillos y falla en tareas avanzadas. Algunas de estas limitaciones son imposibles de superar y requerirán el uso de una biblioteca diferente o de servicios de terceros.

Un servicio gestionado como WebScrapingAPI implementa soluciones para todas estas limitaciones y añade algunas funciones adicionales, como la resolución automática de captchas, proxies residenciales y evasiones avanzadas para evitar que servicios como Akamai, Cloudflare y Datadome detecten tu solicitud. 

A continuación, te presentamos una lista de limitaciones que debes tener en cuenta antes de plantearte utilizar Node Unblocker en tu proyecto de producción.

Problemas con OAuth

OAuth es el estándar de autenticación preferido por sitios modernos como Facebook, Google, YouTube, Instagram y Twitter. Cualquier biblioteca que utilice postMessage no funcionará con Node Unblocker y, como quizá ya hayas adivinado, OAuth requiere postMessage para funcionar correctamente.

Si quieres renunciar al 57 % del tráfico de Internet solo por utilizar esta biblioteca, adelante, añádela a tu proyecto.

Sitios web complejos

Sitios como YouTube, HBO Max, Roblox, Discord e Instagram no funcionan y no hay un plazo previsto para lanzar una versión que permita que estos sitios funcionen. 

Se invita a la comunidad a contribuir con parches para solucionar estos problemas, pero hasta que alguien cree una solicitud de incorporación de cambios, no podrás extraer ningún dato de ellos.

Cloudflare

Cloudflare ofrece un servicio de detección gratuito que está activado por defecto en todas las cuentas. Nuestro servidor proxy personalizado será detectado en segundos y aparecerá un mensaje de captcha en la pantalla.

Alrededor del 80 % de los sitios utilizan la CDN de Cloudflare. Que tus solicitudes sean bloqueadas por un captcha puede suponer el fin de tu rastreador.

Mantenimiento

Aunque configurar un proxy personalizado es fácil, el trabajo de mantenimiento supondrá una carga administrativa enorme y te alejará de tus objetivos empresariales.

Tendrás que ocuparte de ejecutar las instancias de proxy, configurar una infraestructura de autoescalado, gestionar la concurrencia y administrar los clústeres. La lista es interminable.

Conclusión

Ahora tienes un proxy web ejecutándose en Heroku y una buena comprensión de cómo configurarlo, cómo implementarlo y cuáles son sus limitaciones. Si planeas utilizarlo para un proyecto de aficionado, Node Unblocker es una buena opción.

Pero estos inconvenientes y el escaso soporte de la comunidad te impiden utilizarlo en cualquier aplicación lista para producción.

Un servicio gestionado como WebScrapingAPI, que ofrece acceso a un amplio conjunto de proxies de centros de datos, móviles y residenciales, así como la posibilidad de jugar con la geolocalización, cambiar encabezados y crear cookies con un solo parámetro, no tiene ninguna de estas limitaciones.

Acerca del autor
Sorin-Gabriel Marica, Desarrollador full-stack @ WebScrapingAPI
Sorin-Gabriel MaricaDesarrollador full-stack

Sorin Marica es ingeniero Full Stack y DevOps en WebScrapingAPI, donde se encarga de desarrollar funciones para los productos y de mantener la infraestructura que garantiza el buen funcionamiento de la plataforma.

Empieza a crear

¿Estás listo para ampliar tu recopilación de datos?

Únete a más de 2000 empresas que utilizan WebScrapingAPI para extraer datos de la web a escala empresarial sin ningún gasto de infraestructura.