Я пытаюсь очистить три уровня веб-страницы, которые ссылаются друг на друга, например, Домой -> Работа -> Открытые позиции. Затем я хочу записать очищенные данные в файл output.json. Очистка работает просто отлично, но запись файла завершена до того, как запросы будут выполнены из-за их асинхронной природы.
Приведенный ниже код с использованием обычных запросов очищает все данные, но слишком «запаздывает», и поэтому информация не записывается в файл.
request(url, function(error, response, html){
var $ = cheerio.load(html);
$("tr").each(function(i, elem){
var club_url = $(this).children().first().children().attr("href");
club_url = url.substring(0,25) + club_url;
request(club_url, function(error, response, html){
if(!error){
var $ = cheerio.load(html);
var club_name = $("h1.masthead-title").first().text().trim();
console.log(club_name);
clubs[i] = club_name;
var teams = {};
$("tr").each(function(i,elem){
var team_url = $(this).children().first().children().attr("href");
team_url = url.substring(0,25) + team_url;
request(team_url, function(error,response,html){
if(!error){
var $ = cheerio.load(html);
var team = $(".team-name").text().trim();
console.log(team);
teams[i] = team;
}
});
});
}
});
});
fs.writeFile('output.json', JSON.stringify(clubs, null, 4), function(err){
console.log('File successfully written! - Check your project directory for the output.json file');
});
Поэтому я попытался использовать запрос-обещание и переписать код с ним, чтобы запись выполнялась после разрешения обещаний запроса.
app.get('/scrape', function(req, res){
var clubs = {};
url = 'https://norcalpremier.com/clubs/';
var options = {
uri: 'https://norcalpremier.com/clubs/',
transform: function (body) {
return cheerio.load(body);
}
};
rp(options).then(($) => {
var ps = [];
$("tbody tr").each(function(i, elem){
var club_url = $(this).children().first().children().attr("href");
club_url = url.substring(0,25) + club_url;
console.log(club_url);
var club_options = {
uri: club_url,
transform: function (body) {
return cheerio.load(body);
}
};
ps.push(rp(club_options));
});
Promise.all(ps).then((results) =>{
results.forEach((club)=>{
var $ = cheerio.load(club);
var club_name = $("h1.masthead-title").first().text().trim();
console.log(club_name);
clubs[i] = club_name;
})
}).then(()=>{
fs.writeFile('output.json', JSON.stringify(clubs, null, 4), function(err){
console.log('File successfully written! - Check your project directory for the output.json file');
});
res.send('Scraping is done, check the output.json file!');
}).catch(err => console.log(err));
})
})
Тем не менее, я просто не заставляю его работать и получаю ошибку шлюза, как ни странно, после того, как консоль зарегистрировала, что файл был записан. Некоторые из них, я полагаю, не работают сейчас и не ожидают завершения запросов.
Примечание: третий запрос вырезан в этой версии, потому что мне нужно запустить второй уровень первым.
Чего я хочу добиться, так это получить информацию с каждого из сайтов на уровнях 2 и 3, в основном имя, поместить ее в объект JSON, а затем записать ее в файл. Как было сказано ранее, очистка соответствующих данных на уровне 2 и 3 работала в предыдущей версии, но не записывала в файл.
Спасибо, ваша помощь очень ценится!