У меня есть личный проект, в котором я хочу проанализировать данные ассоциации защиты животных Франции (SPA). Поэтому я использую puppeteer, чтобы удалить сайт. Это моя первая программа на node.js. Так что, если у кого-то есть идея, как я могу улучшить скорость этого (1 час, это нормально, но я ищу, чтобы улучшить его!). Это мой сценарий:
const puppeteer = require('puppeteer');
const fs = require('fs');
async function run() {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://www.la-spa.fr/adoption/');
console.info('Page loaded');
// Accept cookies
await page.waitForSelector('#gdpr-accept');
await page.click('#gdpr-accept');
console.info('Cookies accepted');
// Scroll down
for (let i = 0; i < 4; i++) {
await page.evaluate(() => {
window.scrollBy(0, window.innerHeight);
});
await new Promise(resolve => setTimeout(resolve, 5000));
}
console.info('Scrolled down');
let seeMoreActive = true;
let animalData = [];
let processedIds = new Set();
let counter = 0;
while (seeMoreActive) {
counter++;
try {
await page.waitForSelector('.c-see-more_link', { timeout: 5000 });
await page.click('.c-see-more_link');
await new Promise(resolve => setTimeout(resolve, 5000));
} catch (error) {
seeMoreActive = false;
}
// Get new animal data
const newAnimalIds = await page.$$eval('a[data-animal-id]', elements => elements.map(element => element.getAttribute('data-animal-id')));
const newAnimalLinks = await page.$$eval('a[data-animal-id]', elements => elements.map(element => element.href));
const newAnimalRaces = await page.$$eval('a[data-animal-id]', elements => elements.map(element => element.getAttribute('data-animal-race')));
const newAnimalNames = await page.$$eval('a[data-animal-id]', elements => elements.map(element => element.getAttribute('data-animal-nom')));
const newAnimalGenders = await page.$$eval('a[data-animal-id]', elements => elements.map(element => element.getAttribute('data-animal-gender')));
const newAnimalAges = await page.$$eval('a[data-animal-id]', elements => elements.map(element => element.getAttribute('data-animal-age')));
const newAnimalSos = await page.$$eval('a[data-animal-id]', elements => elements.map(element => element.getAttribute('data-animal-sos')));
const newAnimalSpecies = await page.$$eval('a[data-animal-id]', elements => elements.map(element => element.getAttribute('data-animal-espece')));
const newAnimalEstablishments = await page.$$eval('a.f-miniAnimals_establishment span', elements => elements.map(element => element.textContent));
console.info(`Iteration ${counter}:`);
console.info('New Animal IDs:', newAnimalIds);
console.info('New Animal Links:', newAnimalLinks);
console.info('New Animal Races:', newAnimalRaces);
console.info('New Animal Names:', newAnimalNames);
console.info('New Animal Genders:', newAnimalGenders);
console.info('New Animal Ages:', newAnimalAges);
console.info('New Animal SOS:', newAnimalSos);
console.info('New Animal Species:', newAnimalSpecies);
console.info('New Animal Establishments:', newAnimalEstablishments);
// Process new animals
for (let i = 0; i < newAnimalIds.length; i++) {
if (!processedIds.has(newAnimalIds[i])) {
processedIds.add(newAnimalIds[i]);
animalData.push({
id: newAnimalIds[i],
link: newAnimalLinks[i],
race: newAnimalRaces[i],
age: newAnimalAges[i],
sos: newAnimalSos[i],
genders: newAnimalGenders[i],
species: newAnimalSpecies[i],
name: newAnimalNames[i],
establishment: newAnimalEstablishments[i]
});
}
}
}
console.info('Scraping finish');
const timestamp = new Date().getTime();
fs.writeFileSync(`animal_data_${timestamp}.json`, JSON.stringify(animalData, null, 2));
await browser.close();
}
run();
Если вы закомментируете строки console.info, будет ли работать быстрее? Они могут быть дорогими по времени.
Вы можете использовать API, только один запрос менее чем за секунду:
async function getAllPages() {
const baseUrl = "https://www.la-spa.fr/app/wp-json/spa/v1/animals/search/?api=1&seed=1";
const pageCount = await fetch(baseUrl).then(r => r.json()).then(o => o.nb_pages);
const results = await fetch(`${baseUrl}&paged=${pageCount}&full=1`).then(r => r.json()).then(o => o.results);
return results;
}
getAllPages().then(a => console.info(a.length));
Привет @GTK большое спасибо за этот ответ. Кроме того, как вы нашли URL-адрес API для SPA?
@francoisLENNE через инструменты разработчика (F12) > вкладка «Сеть» > фильтр: Fetch/XHR и немного просматриваю код.
Спасибо за ваш ответ !