#javascript #node.js #recursion #web-scraping
#javascript #node.js #рекурсия #веб-очистка
Вопрос:
Пока я могу заставить свой код экспортировать ссылки на первой странице, но у меня возникают проблемы с вставкой ссылок на последующие страницы. Я просто хочу, чтобы он углубился в поиск, просто перейдите по ссылкам один раз, очистите ссылки и вставьте в мой массив объектов, а затем экспортируйте в файл json. Может кто-нибудь, пожалуйста, скажите мне, чего не хватает в моей функции?
const cheerio = require('cheerio');
const fs = require('fs');
const chalk = require('chalk');
const axios = require('axios');
const START_URL = 'https://www.reddit.com/r/Frontend/';
const outputFile = 'data.json';
var results = {};
results.sites = [];
var pagesVisited = {};
var numPagesVisited = 0;
var pagesToVisit = [];
var url = new URL(START_URL);
var baseUrl = url.protocol '//' url.hostname;
var MAX_PAGES_TO_VISIT = 1;
pagesToVisit.push(START_URL);
const crawl = () => {
if (numPagesVisited >= MAX_PAGES_TO_VISIT) {
console.log('Reached max limit of number of pages to visit.');
return;
}
var nextPage = pagesToVisit.pop();
if (nextPage in pagesVisited) {
// We've already visited this page, so repeat the crawl
crawl();
} else {
// New page we haven't visited
collectURLS(nextPage, crawl);
}
};
const collectURLS = async (url, callback) => {
pagesVisited[url] = true;
numPagesVisited ;
const { data } = await axios.get(START_URL);
const $ = cheerio.load(data);
if (results === null) {
$("a[href^='http']").each((i, elem) => {
const link = $(elem).attr('href');
pagesToVisit.push(baseUrl $(this).attr('href'));
if (results === null) {
var obj = {
url: link,
links: [],
};
results.sites.push(obj);
callback();
}
});
} else if (results !== null) {
$("a[href^='http']").each((i, elem) => {
const link = $(elem).attr('href');
results.sites.links.push(link);
});
}
exportResults();
};
//Export results object to json file
const exportResults = () => {
fs.writeFile(outputFile, JSON.stringify(results, null, 4), function (err) {
if (err) throw err;
console.log('complete');
});
console.log(
chalk.black.bgWhite(
`n ${chalk.underline.bold(
results.length
)} Results exported successfully to ${chalk.underline.bold(outputFile)}n`
)
);
};
crawl();
Я хочу, чтобы мой вывод выглядел так
{
"sites": [
{
"url1": "holds this pages link and was scraped from original URL",
"links": [where this URLs scraped links will go]
}
{
"url2": "holds this pages link and was scraped from original URL",
"links": [where this URLs scraped links will go]
}
.
.
.
]
}
Комментарии:
1. Это на самом деле то, с чем вы работали:
var MAX_PAGES_TO_VISIT = 1;
? Потому что это многое объяснило бы!2. да, я запускал его только с этим, но это не оригинальная версия, которая работала
Ответ №1:
Я бы начал с этого, потому что за этим гораздо проще следить:
const crawl = async () => {
var nextPage
while (nextPage = pagesToVisit.pop()) {
await collectURLS(nextPage)
}
exportResults()
}
Также убедитесь, что не используйте this
функции со стрелками, если вы не понимаете разницу с обычными функциями.