Cómo construir un bot de búsqueda simple en 30 minutos

La caza de apartamentos apesta, especialmente en Montreal. Esta guía le mostrará cómo construir un bot que se mantenga al tanto de la búsqueda por usted. De esta manera, nunca más tendrá que actualizar sus búsquedas sin cesar.

Contexto

A diferencia de otras ciudades, la mayoría de las personas que alquilan apartamentos en Montreal tienen el mismo plazo de arrendamiento. Los nuevos arrendamientos comienzan en julio, duran 12 meses y finalizan el 30 de junio. Si bien se podría argumentar que esto simplifica muchas cosas, como la disponibilidad y las expectativas, también significa que la competencia es fuerte.

Todos los días me despertaba, actualizaba mis 10 páginas abiertas de Kijiji y enviaba correos electrónicos preguntando sobre todos los nuevos anuncios. Volvería a hacer esto a la hora del almuerzo, la cena y antes de acostarme. Mi tasa de respuesta fue baja, muy por debajo del 10%. Cuando alguien respondía, su respuesta generalmente era sombría.

Mi siguiente paso fue subir la apuesta y levantar el teléfono. Llamar hizo que mis posibilidades fueran un poco mejores. Los propietarios fueron más receptivos, y esta vez generalmente había menos de 10 personas delante de mí. Pero definitivamente aún más de 5. Volver a la mesa de dibujo.

Un día, mientras me quejaba a un compañero de trabajo de que todo el tiempo estaba siendo devorado por esta búsqueda de apartamentos, me di cuenta. Podría resolver este problema con mi computadora.

Cuando llegué a casa, escribí un pequeño programa que observa cómo Kijiji busca cambios. Cuando los ve, envía un texto del Servicio de mensajes cortos (SMS) a mi teléfono con la información relevante. El resto de este artículo explicará cómo hice eso.

Nota: para aquellos a quienes no les importa el tutorial, he puesto el raspador Kijiji como un repositorio de código abierto aquí:

Edificio Pad-Patrol

Cuando llegué a casa del trabajo, saqué mi computadora portátil y encendí mi terminal. Sabía que el programa debería ser liviano, ya que lo ejecutaré las 24 horas del día, los 7 días de la semana, o al menos hasta que encuentre un apartamento. Decidí crear un script de nodo simple que pudiera ejecutar desde mi terminal.

Preparar

Suponiendo que tiene un nodo y npm instalados, el primer paso, de cualquier proyecto de nodo, es inicializar npm dentro del directorio del proyecto.

A continuación, creemos un directorio src donde vivirá nuestro código.

Dentro del directorio CSS, cree un archivo index.js donde irá nuestro script.

Puedes hacerlo así:

$ npm init // esto hará algunas preguntas
$ mkdir src
$ cd src && touch index.js

Escribiendo el guion

Cuando hago un proyecto en solitario, tiendo al estilo libre: romper cosas y luego arreglarlo (posiblemente la mejor manera de aprender). Intentaré imitar mi proceso de pensamiento inicial con las siguientes instrucciones, pero avíseme si parecen estar por todas partes.

Lo primero que tenemos que hacer es hacer una solicitud exitosa a Kijiji. Para garantizar que podamos obtener una respuesta adecuada, hagamos una búsqueda muy básica.

Para hacer eso, necesitaremos instalar una biblioteca de solicitudes:

$ npm instalar solicitud-promesa

y luego agregue lo siguiente a index.js:

Una vez guardado, podemos ejecutar $ node src / index.js y deberíamos ver un marcado HTML en nuestra consola. Paso uno completo - ¡Fácil!

Debido a que solo nos importa cuando el contenido cambia, hagamos un resumen simple de la respuesta. De esa manera, podemos comparar la respuesta y comparar los hashes. En el caso de que necesitemos registrar nuestros resultados, esto será mucho menos engorroso que el marcado sin procesar.

Para hacer esto, podemos usar una herramienta de hash llamada suma de verificación:

$ hilo agregar suma de verificación

y entonces:

Ok, genial, esto funcionó! Nuestras 1500 líneas de HTML se han reducido a 32 dígitos. Ahora, vamos a envolverlo en una función reutilizable:

El código anterior creará un hash del valor obtenido. Luego, en la siguiente búsqueda, comparará los hashes originales y los nuevos.

Si son diferentes, volverá a ser cierto. Esto funcionó muy bien ... como, un poco demasiado bien. Como verás, vuelve a ser cierto cada vez

Después de una inspección adicional de la respuesta de la búsqueda, podemos ver que Kijiji tiene una marca de tiempo en el encabezado. Esto significa que el hash será diferente en cada búsqueda. Es importante tener en cuenta que esto también habría sucedido debido a la rotación de anuncios y a un montón de otro contenido dinámico.

La conclusión de la supervisión anterior es inspeccionar siempre cuidadosamente su respuesta cuando se trata de una API que no escribió.

Esto significa que tendremos que acceder a bits granulares del marcado, así que instalemos un paquete de terceros para ayudar a analizar la respuesta. Cheerio es una biblioteca que puede ingerir el marcado HTML y convertirlo en una API JavaScript accesible. Su propósito era ayudar a los desarrolladores de jQuery a no usar jQuery, pero las intenciones están sobrevaloradas.

¡Para nosotros, será un conjunto falso de Herramientas para desarrolladores de Chrome!

Como requisito previo para usar Cheerio de esta manera, necesitamos saber qué buscar en nuestro marcado. Así que vamos a abrir Chrome e inspeccionar nuestra URL.

Si inspeccionamos los anuncios, podemos ver que todas las respuestas de búsqueda tienen las clases .search-item y .regular-ad. ¡Perfecto!

Podemos seleccionar aquellos con Cheerio así:

Tal como lo habíamos planeado, esto arroja una serie de objetos perfectamente organizados. Según la documentación de Cheerio, todos los atributos de un elemento están anidados en una clave llamada attribs. Si volvemos a las Herramientas para desarrolladores de Chrome, podemos ver que cada anuncio tiene un atributo de datos único llamado ID. Apuntemos a eso: reemplace el código dentro de su función checkURL con lo siguiente:

rp (siteToCheck) .then (respuesta => {
  const $ = co.load (respuesta HTML);
  let apartmentString = "";
  // usa cheerio para analizar la respuesta HTML y encontrar todos los resultados de búsqueda
  $ (". search-item.regular-ad"). each ((i, element) => {
    console.log (element.attribs ["data-ad-id"]);
  });
});

Ok, genial, estamos obteniendo una lista de números de identificación únicos. Estas identificaciones son la única información que nos interesa en la página.

Así que volvamos a nuestro plan original de comparar hashes, excepto que solo haremos hash de los ID únicos:

¡Perfecto! Funciona exactamente como se esperaba. Cuando alguien publica un anuncio nuevo (o elimina un anuncio antiguo, una advertencia de ver el orden de los ID), imprimimos true en nuestra consola. Todo lo que queda por hacer es configurar nuestra herramienta de SMS.

Enviando SMS desde la Terminal

Esto es en realidad mucho más fácil de lo que parece. Para hacer esto, utilizaremos un software de terceros llamado Twilio. Hace mucho, pero una de sus características principales es enviar SMS. Como beneficio adicional, también tiene una excelente API de JavaScript. Para finalizar el tutorial, necesitará una de sus cuentas, una prueba gratuita será más que suficiente para jugar, y tal vez incluso obtener un nuevo apartamento.

Ok, para comenzar necesitamos ejecutar:

$ hilo agregar twilio

a partir de ahí, en index.js vamos a agregar Twilio y definir una nueva función llamada SMS:

const twilio = requiere (twilio);
// necesitarás obtener tus propias credenciales para esta
cliente const = nuevo Twilio ("ID de cuenta", "authKey");
función SMS ({body, to, from}) {
  mensajes de cliente
    .crear({
      cuerpo,
      a,
      de
    })
    .then (() => {
      console.log (` ¡Éxito! El mensaje ha sido enviado a $ {to}`);
    })
    .catch (err => {
      console.log (err);
    });
}

Esta función simple toma dos números de teléfono (desde y hacia) y un mensaje (cuerpo). En lugar de que la consola registre el resultado de nuestra función checkURL, podemos llamar a SMS con el mensaje que queramos:

¡Ahí tienes! Cada vez que nuestro script ve un cambio entre los hashes del sitio, enviará un mensaje de texto con la URL directamente a su teléfono .

¡Feliz cacería!

El script real que he creado es un poco más complicado que el ejemplo anterior: lo he puesto como repositorio de código abierto en GitHub.

Eventualmente, me gustaría hacer algunas adiciones, la primera de las cuales lo hará más genérico y no solo un raspador Kijiji. Es bastante básico, por lo que será un gran proyecto por primera vez para nuevos contribuyentes.

Siéntase libre de contribuir de la manera que mejor le parezca

Además, en caso de que alguien se lo preguntara, acabo de firmar un contrato de arrendamiento el domingo pasado. El departamento que terminé alquilando fue desde la primera actualización que me envió pad-patrol: fue el destino

Actualmente estoy trabajando como desarrollador de software en la empresa de moda de lujo en Montreal. Lo he estado haciendo durante aproximadamente un año, después de terminar un campamento de desarrollo web el verano pasado. Paso mi tiempo libre aprendiendo tecnología nueva y, hasta hace unos días, buscando apartamentos.