Я столкнулся с некоторым странным поведением при выполнении вложенного цикла for на втором уровне вложенности во фрагменте кода ниже. Журналы, которые я добавил для отладки, следовали этому шаблону:
i: 0
j: 0
j: 0
k: 0
j: 0
j: 0
16/121/61
k: 1
j: 0
j: 0
16/121/01
k: 2
j: 0
j: 0
16/121/02
k: 3
j: 0
j: 0
...
16/121/08
j: 1
j: 1
j: 2
j: 2
j: 3
j: 3
j: 4
j: 4
j: 5
j: 5
j: 6
j: 6
...
17/121/01
i: 1
k: 1
j: 0
j: 0
...
В отличие от того, что я на самом деле ожидал:
i: 0
j: 0
j: 0
k: 0
j: 0
j: 0
16/121/61
k: 1
j: 0
j: 0
16/121/01
k: 2
j: 0
j: 0
16/121/02
k: 3
j: 0
j: 0
...
16/121/08
j: 1
j: 1
k: 1
j: 1
j: 1
17/121/01
j: 1
j: 1
k: 2
j: 1
j: 1
17/121/02
j: 1
j: 1
k: 3
j: 1
j: 1
...
j: 2
j: 2
k: 0
j: 2
j: 2
Кажется, что цикл for выполняет только часть своей области действия на любомитерация:
for (let j = 0; j < courses.length; j++) {
console.log('j: ' + j);
await page.select('#course-select', courses[j]);
await page.waitFor(750);
const groups = await page.evaluate(() => Array.from(document.querySelectorAll('#group-select option:not(:first-child)')).map(group => group.value));
console.log('j: ' + j);
Весь фрагмент кода:
module.exports = (puppeteer) => {
return async () => {
console.log('Timetable scraper started!');
// remove node.js-restrictions, do not delete!!
process.setMaxListeners(Infinity);
const timetables = [];
try {
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
// inject the logs of the browser into the node environment, useful for page.evaluate()
page.on('console', (log) => console[log._type](log._text));
await page.goto('https://www.htw-dresden.de/studium/im-studium/aktuelle-stunden-und-raumplaene');
// fetch all possible timetableIDs
const immatriculationYears = await page.evaluate(() => Array.from(document.querySelectorAll('#mat-select option:not(:first-child)')).map(year => year.value));
for (let i = 0; i < immatriculationYears.length; i++) {
console.log('i: ' + i);
await page.select('#mat-select', immatriculationYears[i]);
await page.waitFor(750);
const courses = await page.evaluate(() => Array.from(document.querySelectorAll('#course-select option:not(:first-child)')).map(course => course.value));
for (let j = 0; j < courses.length; j++) {
console.log('j: ' + j);
await page.select('#course-select', courses[j]);
await page.waitFor(750);
const groups = await page.evaluate(() => Array.from(document.querySelectorAll('#group-select option:not(:first-child)')).map(group => group.value));
console.log('j: ' + j);
for (let k = 0; k < 1; k++) { //groups.length
console.log('k: ' + k);
console.log('j: ' + j);
await page.select('#mat-select', await page.evaluate(() => document.querySelector('#mat-select option').value));
// fill field to request current timetable by format: Year/Course/Group
const timetableID = `${immatriculationYears[i]}/${courses[j]}/${groups[k]}`;
await page.type('#study-group', timetableID);
// navigate to timetable-site
await Promise.all([
page.waitForNavigation({ waitUntil: 'networkidle0' }),
page.click('#select-submit')
]);
// select compact listview of timetable
await Promise.all([
page.waitForSelector('#ui-id-4', {
timeout: 8000
}),
page.click('#ui-id-4'),
]);
await page.waitFor(1000);
console.log('j: ' + j);
// fetch current timetable data
const timetable = await page.evaluate(timetableID => {
const timetableRows = document.querySelectorAll('.list-activity');
const table = {
id: timetableID,
activities: []
};
for (let l = 0; l < timetableRows.length; l++) {
table.activities.push({
title: timetableRows[l].querySelector('.activity-title').innerHTML.trim(),
description: timetableRows[l].querySelector('.activity-description').innerHTML.trim(),
type: timetableRows[l].querySelector('.activity-type').innerHTML.trim(),
day: timetableRows[l].querySelector('td:not([class*="activity"])').innerHTML.trim(),
rotation: timetableRows[l].querySelector('.activity-rotation').innerHTML.trim(),
start: timetableRows[l].querySelector('.activity-start').innerHTML.trim(),
end: timetableRows[l].querySelector('.activity-end').innerHTML.trim(),
location: timetableRows[l].querySelector('.activity-location').innerHTML.trim(),
staff: timetableRows[l].querySelector('.activity-staff').innerHTML.trim(),
});
}
return table;
}, timetableID);
timetables.push(timetable);
console.log(timetable.id);
await page.goto('https://www.htw-dresden.de/studium/im-studium/aktuelle-stunden-und-raumplaene');
}
}
}
console.log('Timetable scraper finnished!');
await browser.close();
} catch (err) {
console.log(`Error while scraping, check for changes on the scraped site! \n ${err}`);
} finally {
console.log(timetables.length);
return timetables;
}
}
};
Кто-нибудь когда-либо сталкивался с таким поведением в этой среде (узел / кукловод) или имеет какие-либо соображения для дальнейшей отладки?
Редактировать: добавлен пример ожидаемого журнала.