Node.js 관련 문서
Итак алгоритм этой работы будет таким:
Перейдём к реализации на JS
Первый и шестой пункт цикла:
const COUNT_REQUEST = 2;
const DELAY_REQUEST = 20000;
/**
* Прибавить в дате countDays дней
* @param {Date} date
* @param {number} countDays
* @returns {Date}
*/
export function addDay(date, countDays = 1) {
const newDate = new Date(date);
return new Date(newDate.setDate(newDate.getDate() + countDays));
}
const startDate = new Date("2020-01-01");
const endDate = new Date("2020-12-31");
let loop = new Date(startDate);
while (loop <= endDate) {
loop = addDay(loop, COUNT_REQUEST);
await delay(DELAY_REQUEST);
}
2. Сформировать список ссылок для первых COUNT_REQUEST дней
/**
* @typedef {Object} UrlData
* @property {Date} date - Запрашиваемый день
* @property {string} url - Ссылка
*/
/**
* Получить массив ссылок для countDays дней
* @param {Date} startDate С какой даты начинать делать ссылки
* @param {number} countDays Сколько ссылок спрашивать
* @param {Date} endDate За какую дату не заходить
* @returns {UrlData}
*/
export function getUrls(startDate, countDays, endDate) {
//--- Текст функции
return urls;
}
3. Запросить праздники для первых COUNT_REQUEST дней
Для этого понадобятся два пакета node-fetch 또는 node-html-parser .
Для реализации использовал фичу из 16 версии nodejs AbortController . Хотя 및 не полностью как в статье сделал,- setTimeout у меня по старинке запускается.
import fetch from "node-fetch";
import { parse } from "node-html-parser";
/**
* Запрос списка праздников
* @param {string} url
* @param {Date} date
* @returns {String[]}
*/
export async function getHolydays(url, date) {
// Для отмены фетча
const cancelFetch = new AbortController();
// Промис запроса к сайту
const promise = fetch(url, {
timeout: REQUEST_TIMEOUT,
signal: cancelFetch.signal,
});
// Время ожидания
const timeout = setTimeout(() => {
cancelFetch.abort();
}, WAIT_REQUEST_TIMEOUT);
try {
const response = await promise;
// Получить текст HTML
const htmlContent = await response.text();
// Получить структуру DOM
const root = parse(htmlContent);
// Массив праздников: DOM-элементы
const source = root.querySelectorAll(".holydays >span");
// Массив праздников: текст
const holidays = source.map((element) => element.textContent);
return { holidays, day: date.getDate(), month: 1 + date.getMonth() };
} catch (e) {
console.log("FetchError :>> ", date);
return null;
} finally {
clearTimeout(timeout);
}
}
// Получить список праздников из массива ссылок
const promisesOfHolidays = await Promise.all(
urlsData.map(async (ud) => await getHolydays(ud.url, ud.date))
);
4. Запомнить праздники
Результат собирается в массив
let holidayData = [];
///
const promisesOfHolidays = await Promise.all(
urlsData.map(async (ud) => await getHolydays(ud.url, ud.date))
);
holidayData = [
...holidayData,
...promisesOfHolidays.filter((r) => r !== null),
];
5. Подождать DELAY_REQUEST секунд
Использую @stanislavkarol/delay
7. JSON에서 После выхода из цикла записать считанные праздники.
import fs from "fs";
import { fileURLToPath } from "url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
if (!fs.existsSync(`${__dirname}/../json`)) {
fs.mkdirSync(`${__dirname}/../json`);
}
fs.writeFile(
`${__dirname}/../json/holidays.json`,
JSON.stringify(holidayData),
(err) => {
if (err) throw err;
console.log("Data written to file");
}
);
Всё вместе, в рабочем виде, на гитхаб .
Reference
이 문제에 관하여(Node.js 관련 문서), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/slkarol/napisal-parsier-saita-27ch텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)