Разработка JS парсера с сохранением результата в SQLite

Разработка JS парсера с сохранением результата в SQLite

Начиная с версии 1.2.152 в A-Parser появилась возможность работать с БД SQLite.
В данной статье мы рассмотрим разработку JavaScript парсера, который будет парсить курсы валют из сайта finance.i.ua и сохранять их в БД, если там этих записей нет, либо обновлять существующие записи.

Идентификатор подключения к бд сделаем константой и присвоим ей значение перед описанием класса.
Код:
const db = 'results/myexchange.sqlite';

В парсере будет две переменных в результате:
  1. текущий курс доллара в украинских гривнах (USD_UA)
  2. текущий курс евро в украинских гривнах (EUR_UA)
Обьявление этих переменных будет выглядеть следующим образом:
Код:
results: {
     flat: [
          ['USD_UA', 'USD finance.i.ua'],
          ['EUR_UA', 'EUR finance.i.ua'],
      ]
},
Начнем с описания метода init, в котором будут создаваться таблицы если их нет, а также если таблица currencies пустая, то заполнять её.
Код:
 /*Если в бд нет таблиц, то создаем их, также если в таблице  currencies нет записей то добавляем их*/
    init() {
        tools.sqlite.run(db, `CREATE TABLE IF NOT EXISTS currencies(
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            name varchar(50)
        )`);

        tools.sqlite.run(db, `CREATE TABLE IF NOT EXISTS exchange_rates(
          id INTEGER PRIMARY KEY AUTOINCREMENT,
          rate FLOAT NOT NULL,
          currency_id INTEGER
        )`);

        if(!tools.sqlite.get(db, 'SELECT COUNT(*) AS count FROM currencies').count) {
            tools.sqlite.run(db, 'INSERT INTO currencies(name) VALUES("USD"), ("EUR")');
        };
    }
Теперь напишем метод, который будет делать запрос, выбирать из тела страницы интересующую нас информацию и возращать эти данные в хеше.
Код:
/*метод собирающий курс доллара и  евро с сайта*/
    *getFinanceIUa(currencies) {
        let rates = {};

        let response = yield this.request('GET', 'https://finance.i.ua/converter/', {}, {
            check_content: ['<\/html>'],
            decode: 'auto-html',
        });

        if (response.success) {
            for(const currency of currencies) {
                const regex = new RegExp(`"${currency}":\\{"buy":(.*?),`);
                const matches = response.data.match(regex);
                if(matches) {
                    rates[currency] = matches[1];
                };
            };
            return rates;
        }

        return false;
    }

Сама база данных будет состоять из двух таблиц:
  1. currencies в которой будут храниться виды валют
  2. exchange_rates в которой будут храниться курсы валют
Следующим шагом будет описание метода, который возвращает строку записи из таблицы курсов exchange_rates, или false, если такой записи нет. Принимать в качестве параметра он будет id валюты.
Код:
 /*метод который  ищет по таблице exhange_rates есть ли запись для такой валюты*/
    getCurrencyExchangeId(db, currency_id) {
        const result = tools.sqlite.get(db, 'SELECT id FROM exchange_rates WHERE currency_id = ?', currency_id);
        if (result) {
            return result.id;
        }
        return false;
    }

И в завершение, опишем в методе parse логику работы нашего парсера. В зависимости от наличия записи о данной валюте в таблице либо обновляем значение, либо добавляем новое.
Код:
*parse(set, results) {
        /*получаем массив валют*/
        const currencies = tools.sqlite.all(db, 'SELECT * FROM currencies');
        /*получаем данные по этим валютам с сайта*/
        const rates = yield* this.getFinanceIUa(currencies.map(el => el.name));
        if(rates) {
            results.success = 1;
            /*перебираем в цикле массив валют и в каждом витке цикла либо обновляем значение в таблице, либо добавляем если такого значения нет*/
            for(const currency of currencies) {
                const id = this.getCurrencyExchangeId(db, currency.id);
                if(id) {
                    tools.sqlite.run(db, 'UPDATE exchange_rates SET rate = ? WHERE id = ?', rates[currency.name], id);
                }
                else {
                    tools.sqlite.run(db, 'INSERT INTO exchange_rates(currency_id, rate) values(?, ?)', currency.id, rates[currency.name]);
                };
              
                results[currency.name + '_UA'] = rates[currency.name];
            };
        };

        return results;
    }
Пресет с уже готовым парсером опубликован в Каталоге по этой ссылке.
Автор
Support Денис
Просмотры
57
Первый выпуск
Обновление

Рейтинги

0,00 звёзд Оценок: 0

Ещё ресурсы от Support Денис

Назад
Верх