Як створити простий пошуковий бот за 30 хвилин

Полювання на квартири відстійне, особливо в Монреалі. Цей посібник покаже вам, як створити бота, який залишатиметься над вами на полюванні. Таким чином, вам більше ніколи не доведеться нескінченно оновлювати пошукові запити.

Контекст

На відміну від інших міст, більшість людей, які знімають квартири в Монреалі, мають однаковий термін оренди. Нова оренда починається в липні, останні 12 місяців, і закінчується 30 червня. Хоча можна стверджувати, що це спрощує багато речей, таких як доступність та очікування, це також означає, що конкуренція крута.

Щодня я прокидався, оновлював свої 10 відкритих сторінок Кідзідзі та надсилав електронні листи із запитами про всі нові оголошення. Я б робив це знову в обід, вечерю і перед сном. Моя відповідь була низькою - значно нижче 10%. Коли хтось відповідав, їх відповідь, як правило, була похмурою.

Наступним моїм кроком було підняття ставки та фактичне підняття слухавки. Телефонування зробило мої шанси трохи кращими. Поміщики були більш чуйними, і цього разу, як правило, переді мною було менше 10 людей. Але однозначно все-таки більше 5. Повернімося до креслення.

Одного разу, поскаржившись колезі, що весь мій час з’їдає це полювання на квартиру, мене осяяло. Я міг би вирішити цю проблему за допомогою комп’ютера.

Повернувшись додому, я написав невеличку програму, яка спостерігає, як Кідзідзі шукає зміни. Побачивши їх, він надсилає текст служби коротких повідомлень (SMS) на мій телефон із відповідною інформацією. Далі в цій статті буде пояснено, як я це зробив.

Примітка: для тих, хто не піклується про підручник, я поставив скребок Kijiji як репо з відкритим кодом тут:?

Будівництво Pad-Patrol

Коли я приїхав з роботи додому, я дістав ноутбук і запалив термінал. Я знав, що програма повинна бути легкою, оскільки я буду запускати її цілодобово - або принаймні доти, поки не знайду квартиру. Я вирішив просто створити простий сценарій вузла, який я міг би виконати з мого терміналу.

Налаштування

Якщо припустити, що ви встановили nodeта npmвстановили, перший крок - будь-якого проекту вузла - це ініціалізація npm всередині каталогу проекту.

Далі, давайте створимо srcкаталог, де буде жити наш код.

Всередині srcкаталогу створіть index.jsфайл, куди буде переходити наш сценарій.

Ви можете зробити це так:

$ npm init // this will ask a few questions$ mkdir src$ cd src && touch index.js

Написання сценарію

Роблячи сольний проект, я схильний до фрістайлу - ламати речі, а потім виправляти їх (мабуть, найкращий спосіб вчитися). Я спробую імітувати свій початковий процес думок, дотримуючись наведених нижче інструкцій, але дайте мені знати, чи вони здаються повсюдно.

Найперше, що нам потрібно зробити, це зробити успішний запит до Кідзідзі. Щоб ми могли отримати належну відповідь, давайте зробимо дуже базовий вибір.

Для цього нам потрібно встановити бібліотеку запитів:

$ npm install request-promise

а потім додайте наступне до index.js:

Після того, як це буде збережено, ми можемо запустити, $ node src/index.jsі ми повинні побачити деяку розмітку HTML на нашій консолі. Крок перший повний - Легко!

Оскільки нас турбує лише зміна вмісту, давайте зробимо простий хеш відповіді. Таким чином, ми можемо порівняти відповідь і порівняти хеші. У випадку, якщо нам потрібно буде реєструвати наші результати, це буде набагато менш громіздким, ніж вихідна розмітка.

Для цього ми можемо використовувати інструмент хешування, який називається checksum:

$ yarn add checksum

і потім:

Добре класно, це спрацювало! Наші 1500 рядків HTML скорочено до 32 цифр. Тепер обернемо його у багаторазову функцію:

Наведений вище код створить хеш із отриманого значення. Потім при наступному завантаженні він порівняє вихідний та новий хеш.

Якщо вони різні, це повернеться true. Це спрацювало чудово ... начебто, занадто чудово. Як побачите, воно повертається trueщоразу?

Після подальшої перевірки відповіді від завантаження ми можемо побачити, що Кідзідзі має відмітку часу в заголовку. Це означає, що хеш буде різним для кожного завантаження. Важливо зазначити, що це також могло статися через обертаються рекламу та купу іншого динамічного вмісту.

Висновок вищезазначеного нагляду полягає в тому, щоб завжди ретельно перевіряти свою відповідь, маючи справу з API, який ви не писали.

Це означає, що нам потрібно буде отримати доступ до деталізованих бітів розмітки, тому давайте встановимо сторонній пакет, щоб допомогти проаналізувати відповідь. Cheerio - це бібліотека, яка може проковтувати розмітку HTML і перетворювати її на доступний API JavaScript. Його метою було допомогти jQueryрозробникам не використовувати jQuery, але наміри завищені.

Для нас це буде підроблений набір інструментів розробника Chrome!

Як необхідна умова використання Cheerio таким чином, ми повинні знати, на що слід звертати увагу у нашій розмітці. Тож давайте відкриємо Chrome і перевіримо нашу URL-адресу.

Якщо ми перевіримо рекламу, ми побачимо, що всі відповіді на пошукові запити мають класи .search-itemта .regular-ad. Ідеально!

Ми можемо вибрати таких із Cheerio так:

Як і ми планували, це випльовує безліч акуратно організованих об’єктів. Згідно з документацією Cheerio, всі атрибути елемента вкладені в ключ, який називається attribs. Якщо ми повернемося до Інструментів розробника Chrome, то побачимо, що кожне оголошення має унікальний атрибут даних, який називається ID. Давайте націлимося на це - замінимо код всередині вашої checkURLфункції таким:

rp(siteToCheck).then(response => { const $ = co.load(HTMLresponse); let apartmentString = "";
 // use cheerio to parse HTML response and find all search results $(".search-item.regular-ad").each((i, element) => { console.log(element.attribs["data-ad-id"]); });});

Гаразд, чудово, ми отримуємо список унікальних ідентифікаційних номерів. Ці посвідчення особи - це єдина інформація, яка нас турбує на сторінці.

Тож повернімось до нашого початкового плану порівняння хешів, за винятком того, що ми будемо хешувати лише унікальні ідентифікатори:

Ідеально! Це працює точно так, як задумано. Коли хтось розміщує нову рекламу (або видаляє стару рекламу, застереження щодо перегляду порядку посвідчень особи), ми друкуємо trueна нашій консолі. Все, що залишилось для цього, - це налаштування нашого інструмента SMS.

Надсилання SMS з терміналу

Це насправді набагато простіше, ніж здається. Для цього ми використаємо програмне забезпечення третьої сторони під назвою Twilio. Це робить багато, але однією з основних функцій є надсилання SMS. Як бонус, він також має чудовий API JavaScript! Щоб закінчити підручник, вам знадобиться один з їхніх акаунтів - безкоштовної пробної версії буде більш ніж достатньо, щоб пограти - і, можливо, навіть отримати нову квартиру.

Гаразд, для початку нам потрібно запустити:

$ yarn add twilio

звідти, index.jsдавайте додамо Twilio і визначимо нову функцію з назвою SMS:

const twilio = require(twilio);
// you'll need to get your own credentials for this oneconst client = new Twilio("accountID", "authKey");
function SMS({ body, to, from }) { client.messages .create({ body, to, from }) .then(() => { console.log(`? Success! Message has been sent to ${to}`); }) .catch(err => { console.log(err); });} 

This simple function takes two phone numbers (to and from) and a message (body). Instead of console logging the result of our checkURL function, we can call SMS with whatever message we want:

There you have it! Every time our script sees a change between the site hashes, it will send a text message with the URL right to your phone ?.

Happy Hunting!

The actual script that I’ve built is a little more complicated than the above example — I’ve put it up as an open source repo on GitHub.

Eventually, I’d like to make some additions to it — the first of which will be making it more generic and not just a Kijiji scraper. It’s pretty basic, so it will be a great first-time project for new contributors.

Feel free to contribute in any way you see fit ?

Also, in case anyone was wondering, I just signed a lease last Sunday. The apartment I ended up renting was from the very first update pad-patrol sent me — it was destiny ✨

I’m currently working as a software developer at luxury fashion company in Montreal. I’ve been doing that for about a year, after finishing a web dev bootcamp last summer. I spend my free time learning hot new tech and, up until a few days ago, hunting for apartments.