Hogyan készítsünk egy egyszerű keresőrobotot 30 perc alatt

A lakásvadászat szar, főleg Montrealban. Ez az útmutató megmutatja, hogyan lehet egy botot felépíteni, amely a vadászat tetején marad. Így soha nem kell többé végtelenül frissítenie a kereséseit.

Kontextus

Más városokkal ellentétben a montreali lakást bérlő emberek többsége azonos bérleti idővel rendelkezik. Az új bérleti szerződések júliusban, utolsó 12 hónapban kezdődnek és június 30-án érnek véget. Bár lehet vitatni, hogy ez sok mindent leegyszerűsít - például a rendelkezésre állást és az elvárásokat -, ez azt is jelenti, hogy a verseny éles.

Minden nap felébredtem, frissítettem a 10 nyitott Kijiji oldalamat, és e-maileket küldtem az összes új hirdetésről. Ezt megint megcsinálom ebédnél, vacsoránál és lefekvés előtt. A válaszadási arányom alacsony volt - jóval 10% alatt. Amikor valaki válaszolt, a válasza általában komor volt.

A következő lépésem az volt, hogy felvegyem az előzetest, és valóban felvegyem a telefont. A hívás egy kicsit javította az esélyeimet. A bérbeadók jobban reagáltak, és ezúttal általában kevesebb, mint 10 ember állt előttem. De mindenképpen több, mint 5. Vissza a rajztáblához.

Egy nap, miközben panaszkodtam egy munkatársamnak, hogy minden időmet megeszi ez a lakásvadászat - megfogalmazódott bennem. Meg tudnám oldani ezt a problémát a számítógépemmel.

Amikor hazaértem, írtam egy kis programot, amely azt figyeli, hogy Kijiji hogyan keresi a változásokat. Amikor meglátja őket, SMS-t küld a telefonomra a vonatkozó információkkal együtt. A cikk további része elmagyarázza, hogyan tettem ezt.

Megjegyzés: Azok számára, akiket nem érdekel a bemutató, itt tettem fel a Kijiji kaparót nyílt forráskódú repóként:?

Pad-Patrol épület

Amikor hazaértem a munkából, elővettem a laptopomat és felgyújtottam a terminálomat. Tudtam, hogy a programnak könnyűnek kell lennie, mivel a nap 24 órájában fogok működni - vagy legalábbis addig, amíg nem találok lakást. Úgy döntöttem, hogy csak felépítek egy egyszerű csomópont-szkriptet, amelyet a terminálról futtathatok.

Beállít

Feltéve, hogy rendelkezik nodeés npmtelepített, minden csomópont projekt első lépése az npm inicializálása a projektkönyvtárban.

Ezután hozzunk létre egy srckönyvtárat, ahol a kódunk élni fog.

A srckönyvtárban készítsen egy index.jsfájlt, ahová a szkriptünk kerül.

Ezt megteheti így:

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

A forgatókönyv írása

Egyéni projekt készítésekor hajlamos vagyok freestyle-ra törni a dolgokat, majd javítani (vitathatatlanul a legjobb módszer a tanuláshoz). Megpróbálom utánozni a kezdeti gondolkodási folyamatomat a következő utasításokkal, de tudassa velem, ha mindenhol úgy tűnik.

A legelső dolog, amit meg kell tennünk, sikeres kérelmet kell benyújtanunk Kijijihez. Annak biztosítása érdekében, hogy megfelelő választ tudjunk kapni, végezzünk el egy nagyon egyszerű lekérdezést.

Ehhez telepítenünk kell egy kérelem könyvtárat:

$ npm install request-promise

majd adja hozzá a következőket index.js:

A mentés után futtatható, $ node src/index.jsés látnunk kell egy HTML jelölést a konzolunkon. Első lépés teljes - Könnyű!

Mivel csak akkor törődünk, ha a tartalom megváltozik, lehetővé teszi a válasz egyszerű kivonatolását. Így összehasonlíthatjuk a választ és összehasonlíthatjuk a kivonatokat. Abban az esetben, ha naplóznunk kell az eredményeinket, ez sokkal kevésbé lesz nehézkes, mint a nyers jelölés.

Ehhez használhatunk egy hash eszközt checksum:

$ yarn add checksum

és akkor:

Rendben, ez sikerült! 1500 HTML-sorunk 32 jegyűre lett vágva. Most csomagoljuk be egy újrafelhasználható funkcióba:

A fenti kód kivonatot hoz létre a beolvasott értékből. A következő lekéréskor összehasonlítja az eredeti és az új hasheket.

Ha különböznek, akkor visszatér true. Ez remekül működött ... mint egy kicsit. Mint látni fogja, trueminden alkalommal visszatér ?

A lekérés válaszának további ellenőrzése után láthatjuk, hogy Kijiji időbélyeggel rendelkezik a fejlécben. Ez azt jelenti, hogy a hash minden lekéréskor más és más lesz. Fontos megjegyezni, hogy ez a hirdetések váltakozása és egy csomó más dinamikus tartalom miatt is megtörtént volna.

A fenti felügyelet elvétele az, hogy mindig gondosan ellenőrizze válaszát, amikor olyan API-val foglalkozik, amelyet nem Ön írt.

Ez azt jelenti, hogy hozzá kell férnünk a jelölés részletekhez, ezért telepítsünk egy harmadik féltől származó csomagot a válasz elemzéséhez. A Cheerio egy olyan könyvtár, amely beolvashatja a HTML jelöléseket, és hozzáférhető JavaScript API-kká alakíthatja. Célja az volt, hogy segítse a jQueryfejlesztőket abban , hogy ne használják jQuery, de a szándékokat túlértékelik.

Számunkra ez a Chrome Developer Tools hamis készlete lesz!

A Cheerio ilyen jellegű használatának előfeltételeként tudnunk kell, hogy mire figyeljünk a jelölőnkben. Nyissuk meg tehát a Chrome-ot, és vizsgáljuk meg az URL-jünket.

Ha mi vizsgáljuk meg a hirdetéseket, akkor az összes keresési válaszok van az osztályok .search-itemés .regular-ad. Tökéletes!

Kiválaszthatjuk a Cheerio-val rendelkezőket:

Ahogy terveztük, ez egy sor rendezett tárgyat köp ki. Cheerio dokumentációja szerint egy elem minden attribútuma be van ágyazva egy úgynevezett kulcsba attribs. Ha visszatérünk a Chrome fejlesztői eszközökhöz, láthatjuk, hogy minden hirdetésnek egyedi adatattribútuma van, az úgynevezett ID. Célozzuk meg ezt - cserélje le a checkURLfunkciójában lévő kódot a következőkre:

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"]); });});

Rendben, kapunk egy listát egyedi azonosító számokról. Ezek az azonosítók az egyetlen információ, amely az oldalon érdekel.

So let’s go back to our original plan of comparing hashes, except we’ll only hash the unique IDs:

Perfect! It’s working exactly as intended. When someone posts a new ad (or removes an old ad, a caveat of watching the order of IDs) we print true in our console. All that’s left to do it set up our SMS tool.

Sending SMS from the Terminal

This is actually much easier than it seems. To do this we’ll use a third party software called Twilio. It does a lot, but one of it’s core features is to send SMS. As a bonus, it also has great JavaScript API! To finish the tutorial, you’ll need one of their accounts — a free trial will be more than enough to play around — and maybe even get a new apartment.

Ok, so to start we need to run:

$ yarn add twilio

from there, in index.js lets add Twilio and define a new function called 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.