Как пометить страницу, когда она была просмотрена? - PullRequest
0 голосов
/ 22 апреля 2020

Сводка приложения

Это приложение должно уведомлять пользователя, когда НОВЫЙ автомобиль был опубликован на Facebook MarketPlace. Пользователь получит электронное письмо с уведомлением о них и включит ссылку, по которой можно щелкнуть мышью, чтобы перейти на страницу с таблицей транспортных средств.

Прогресс

До сих пор я добился большого прогресса: 1007 *

  1. Я заполнил страницу с результатами, как показано здесь (таблица пуста, только заголовки и нижние колонтитулы)

App

Код PHP работает для отправки пользователю электронного письма при публикации нового автомобиля:
<?php

$subject = 'New Vehicles Found - MPB';

$headers = "From: bot@mpb.com\r\n";
$headers .= "Reply-To: bot@mpb.com\r\n";
$headers .= "CC: admin@gmail.com.com\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n";

$message = '<html><body>';
$message .= '<h1>MarketPlace Bot Found Vehicles</h1>';
$message .= '<p><a href="http://john.123globalelectronicsllc.com/mpb/results.html">Click here to see new vehicles</a>';
$message .= '</body></html>';

$to = 'test@gmail.com,admin@gmail.com';

            if (mail($to, $subject, $message, $headers)) {
              echo 'Your message has been sent.';
            } else {
              echo 'There was a problem sending the email.';
            }
?>

Сценарий NODE JS до этого момента будет использовать Puppeteer для очистки данных, необходимых со страницы результатов поиска. Следующий код не работает так, как мне нужно, по причине, указанной в следующем разделе.
// CRON JOB THIS FOR EVERY TEN MINUTES


const puppeteer = require('puppeteer');


/* InitScraper
*  
*  @desc: Get Vehicle Listings From FaceBook MarketPlace
*  @param:      string  searchTerm  The complete URL including search term
*  @example:    getItems('')               
*/
const getItems = async searchTerm => {

    if(searchTerm == ''){
        /* Define Jeep Wrangler as default */
        var searchTerm = "Jeep Wrangler";
    }

    /* Configure Puppeteer */
    const browser = await puppeteer.launch({
        headless: true,
        defaultViewport: null
    });

    /* Create New Puppeteer Page */
    const page = await browser.newPage();

    /* Go to page */
    await page.goto(`https://facebook.com/marketplace/tampa/search/?query=${encodeURI(searchTerm)}`);

    /* Find Listing Container */
    const itemList = await page.waitForSelector('div > div > span > div > a[tabindex="0"]')
        .then(() => page.evaluate(() => {

            const itemArray = [];

            // Define Selector To Find Vehicle Listings
            const itemNodeList = document.querySelectorAll('div > div > span > div > a[tabindex="0"]');

            // Loop through listing, get TITLE, PRICE, URL, IMAGE
            itemNodeList.forEach(item => {

                /* Properties of A Listing */
                const itemTitle = item.querySelector('div > div > span > div > a > div > div > div > span > div > span > div[class="l9j0dhe7 stjgntxs ni8dbmo4"').innerText;
                const itemPrice = item.querySelector('div > div > span > div > a > div > div > div > div > span[class="oi732d6d ik7dh3pa d2edcug0 qv66sw1b c1et5uql a8c37x1j s89635nw ew0dbk1b a5q79mjw g1cxx5fr lrazzd5p oo9gr5id"').innerText;
                const itemURL = `https://facebook.com/${item.getAttribute('href')}`;
                const itemImg = item.querySelector('div > div > span > div > a > div > div > div > div > div > div > img').getAttribute('src');
                /* Unique Item Number [ADDED] */
                const itemNum = getItemNumber(itemURL);

                /* Add Vehicle To Array */
                itemArray.push({
                    itemNum,
                    itemTitle,
                    itemPrice,
                    itemURL,
                    itemImg
                });

            });

            return itemArray;

        }))
        /* Selector Not Found - Log Error To Console */
        .catch(() => console.log("Selector error."));

        /*--------------------------*/
        /* Create / Save Screenshot */
        /*--------------------------*/
        await page.screenshot({
            path: 'screenshot.png'
        });

    return itemList;

}

/* InitScraper
*  
*  @desc: Initialize page, scrape MarketPlace and save the
*                results to JSON file. 
*/
const initScraper = async () => {

    const items = await getItems('');

    /* Sort by Price */
    items.sort(function (a, b) {
        return a.itemPrice - b.itemPrice
    });

    /* Save results to JSON file */
    fs.writeFile("marketplacebot.json", JSON.stringify(items), function (err) {
        if (err) throw err;
        console.log("Saved!");
    });

    console.log(items);
}

/* Get Item Number From URL String
*
*  @desc    This function extracts the item number from a Facebook URL
*  @param   string  url      The FaceBook MarketPlace Listing URL 
*  @return  string  itemNum  The item number
*/
const getItemNumber = function(url){
    var itemNum = 0;
    var re = /(\d{10,})/ig;
    var itemNum = url.match(re)[0];
    return itemNum;
}

// Away we go...
initScraper();

ПРОБЛЕМА

Если задание CRON выполняется каждые десять минут, как я отделил бы данные, собранные, когда скрипт Node выполняется? В первый раз пользователь получит все списки. Но после этого каждые десять минут мне как-то приходится показывать только новые.

Я записываю все списки в файл JSON, на рынке. json

Так или иначе, Мне нужно получить новые списки, загрузить старые JSON файлы и показать только те, которых нет на рынке. json, верно? Если так, то как в мире это может быть сделано? Я не являюсь автором Узла, кстати.

Спасибо за любую помощь.

С уважением,

Джон

...