update
This commit is contained in:
@@ -92,20 +92,36 @@ export async function scrapeAll(username: string, password: string): Promise<{
|
||||
member.wohnort = profileFields.wohnort;
|
||||
member.plz = profileFields.plz;
|
||||
|
||||
// Extract mitgliedschaft params from the current URL for constructing sub-section URLs.
|
||||
// PersonenForm.aspx is in the personen module; sub-sections are in mitgliedschaften module.
|
||||
// The links to Beförderungen/Untersuchungen/Fahrgenehmigungen live in the navigation
|
||||
// frame (not the content mainFrame), so we construct the URLs directly.
|
||||
const currentUrl = mainFrame.url();
|
||||
const urlObj = new URL(currentUrl);
|
||||
const idMitgliedschaft = urlObj.searchParams.get('id_mitgliedschaften');
|
||||
const idInstanzen = urlObj.searchParams.get('id_instanzen') ?? ID_INSTANZEN;
|
||||
const idFeuerwehren = urlObj.searchParams.get('id_feuerwehren') ?? ID_FEUERWEHREN;
|
||||
|
||||
// Ausbildungen
|
||||
const quals = await scrapeAusbildungenFromDetailPage(mainFrame, member);
|
||||
ausbildungen.push(...quals);
|
||||
|
||||
// Beförderungen
|
||||
const befos = await scrapeMemberBefoerderungen(mainFrame, member.standesbuchNr);
|
||||
const befos = idMitgliedschaft
|
||||
? await scrapeMemberBefoerderungen(mainFrame, member.standesbuchNr, idMitgliedschaft, idInstanzen, idFeuerwehren)
|
||||
: [];
|
||||
befoerderungen.push(...befos);
|
||||
|
||||
// Untersuchungen
|
||||
const unters = await scrapeMemberUntersuchungen(mainFrame, member.standesbuchNr);
|
||||
const unters = idMitgliedschaft
|
||||
? await scrapeMemberUntersuchungen(mainFrame, member.standesbuchNr, idMitgliedschaft, idInstanzen, idFeuerwehren)
|
||||
: [];
|
||||
untersuchungen.push(...unters);
|
||||
|
||||
// Fahrgenehmigungen
|
||||
const fahrg = await scrapeMemberFahrgenehmigungen(mainFrame, member.standesbuchNr);
|
||||
const fahrg = idMitgliedschaft
|
||||
? await scrapeMemberFahrgenehmigungen(mainFrame, member.standesbuchNr, idMitgliedschaft, idInstanzen, idFeuerwehren)
|
||||
: [];
|
||||
fahrgenehmigungen.push(...fahrg);
|
||||
|
||||
log(` ${member.vorname} ${member.zuname}: ${quals.length} Ausbildungen, ${befos.length} Beförderungen, ${unters.length} Untersuchungen, ${fahrg.length} Fahrgenehmigungen`);
|
||||
@@ -602,21 +618,17 @@ async function scrapeAusbildungenFromDetailPage(frame: Frame, member: FdiskMembe
|
||||
|
||||
/**
|
||||
* Navigate to the Beförderungen sub-page and scrape all promotions.
|
||||
* Navigates back to the member detail page afterwards.
|
||||
* URL is constructed from the mitgliedschaft ID extracted from PersonenForm URL.
|
||||
*/
|
||||
async function scrapeMemberBefoerderungen(frame: Frame, standesbuchNr: string): Promise<FdiskBefoerderung[]> {
|
||||
// Find sidebar link to Beförderungen
|
||||
const link = frame.locator('a[href*="befoerderungenList.aspx"], a[href*="BefoerderungenList.aspx"]').first();
|
||||
const hasLink = await link.isVisible().catch(() => false);
|
||||
if (!hasLink) {
|
||||
log(` No Beförderungen link for StNr ${standesbuchNr}`);
|
||||
return [];
|
||||
}
|
||||
|
||||
const href = await link.getAttribute('href');
|
||||
if (!href) return [];
|
||||
|
||||
const url = href.startsWith('http') ? href : new URL(href, frame.url()).toString();
|
||||
async function scrapeMemberBefoerderungen(
|
||||
frame: Frame,
|
||||
standesbuchNr: string,
|
||||
idMitgliedschaft: string,
|
||||
idInstanzen: string,
|
||||
idFeuerwehren: string,
|
||||
): Promise<FdiskBefoerderung[]> {
|
||||
const url = `${BASE_URL}/fdisk/module/mgvw/mitgliedschaften/befoerderungenList.aspx`
|
||||
+ `?id_mitgliedschaften=${idMitgliedschaft}&id_instanzen=${idInstanzen}&id_feuerwehren=${idFeuerwehren}`;
|
||||
await frame_goto(frame, url);
|
||||
|
||||
const results: FdiskBefoerderung[] = [];
|
||||
@@ -643,7 +655,7 @@ async function scrapeMemberBefoerderungen(frame: Frame, standesbuchNr: string):
|
||||
log(` ${b.datum ?? '—'} ${b.dienstgrad}`);
|
||||
}
|
||||
} catch {
|
||||
log(` WARN: could not parse Beförderungen table for StNr ${standesbuchNr}`);
|
||||
log(` WARN: could not parse Beförderungen table for StNr ${standesbuchNr} (url: ${url})`);
|
||||
}
|
||||
|
||||
return results;
|
||||
@@ -653,18 +665,15 @@ async function scrapeMemberBefoerderungen(frame: Frame, standesbuchNr: string):
|
||||
* Navigate to the Untersuchungen sub-page and scrape all medical exams.
|
||||
* Keeps all rows (one per art+datum); DB stores all, queries filter latest per category.
|
||||
*/
|
||||
async function scrapeMemberUntersuchungen(frame: Frame, standesbuchNr: string): Promise<FdiskUntersuchung[]> {
|
||||
const link = frame.locator('a[href*="UntersuchungenList.aspx"]').first();
|
||||
const hasLink = await link.isVisible().catch(() => false);
|
||||
if (!hasLink) {
|
||||
log(` No Untersuchungen link for StNr ${standesbuchNr}`);
|
||||
return [];
|
||||
}
|
||||
|
||||
const href = await link.getAttribute('href');
|
||||
if (!href) return [];
|
||||
|
||||
const url = href.startsWith('http') ? href : new URL(href, frame.url()).toString();
|
||||
async function scrapeMemberUntersuchungen(
|
||||
frame: Frame,
|
||||
standesbuchNr: string,
|
||||
idMitgliedschaft: string,
|
||||
idInstanzen: string,
|
||||
idFeuerwehren: string,
|
||||
): Promise<FdiskUntersuchung[]> {
|
||||
const url = `${BASE_URL}/fdisk/module/mgvw/mitgliedschaften/UntersuchungenList.aspx`
|
||||
+ `?id_mitgliedschaften=${idMitgliedschaft}&id_instanzen=${idInstanzen}&id_feuerwehren=${idFeuerwehren}`;
|
||||
await frame_goto(frame, url);
|
||||
|
||||
const results: FdiskUntersuchung[] = [];
|
||||
@@ -704,7 +713,7 @@ async function scrapeMemberUntersuchungen(frame: Frame, standesbuchNr: string):
|
||||
log(` ${u.datum ?? '—'} [${u.art}] ${u.ergebnis ?? '—'} | ${u.anmerkungen ?? ''}`);
|
||||
}
|
||||
} catch {
|
||||
log(` WARN: could not parse Untersuchungen table for StNr ${standesbuchNr}`);
|
||||
log(` WARN: could not parse Untersuchungen table for StNr ${standesbuchNr} (url: ${url})`);
|
||||
}
|
||||
|
||||
return results;
|
||||
@@ -714,18 +723,15 @@ async function scrapeMemberUntersuchungen(frame: Frame, standesbuchNr: string):
|
||||
* Navigate to the Gesetzliche Fahrgenehmigungen sub-page and scrape all entries.
|
||||
* This is an inline-edit (ListEdit) page — values are in <input> fields.
|
||||
*/
|
||||
async function scrapeMemberFahrgenehmigungen(frame: Frame, standesbuchNr: string): Promise<FdiskFahrgenehmigung[]> {
|
||||
const link = frame.locator('a[href*="Ges_fahrgenehmigungenListEdit.aspx"], a[href*="ges_fahrgenehmigungenListEdit.aspx"]').first();
|
||||
const hasLink = await link.isVisible().catch(() => false);
|
||||
if (!hasLink) {
|
||||
log(` No Fahrgenehmigungen link for StNr ${standesbuchNr}`);
|
||||
return [];
|
||||
}
|
||||
|
||||
const href = await link.getAttribute('href');
|
||||
if (!href) return [];
|
||||
|
||||
const url = href.startsWith('http') ? href : new URL(href, frame.url()).toString();
|
||||
async function scrapeMemberFahrgenehmigungen(
|
||||
frame: Frame,
|
||||
standesbuchNr: string,
|
||||
idMitgliedschaft: string,
|
||||
idInstanzen: string,
|
||||
idFeuerwehren: string,
|
||||
): Promise<FdiskFahrgenehmigung[]> {
|
||||
const url = `${BASE_URL}/fdisk/module/mgvw/mitgliedschaften/Ges_fahrgenehmigungenListEdit.aspx`
|
||||
+ `?id_mitgliedschaften=${idMitgliedschaft}&id_instanzen=${idInstanzen}&id_feuerwehren=${idFeuerwehren}`;
|
||||
await frame_goto(frame, url);
|
||||
|
||||
const results: FdiskFahrgenehmigung[] = [];
|
||||
@@ -741,7 +747,6 @@ async function scrapeMemberFahrgenehmigungen(frame: Frame, standesbuchNr: string
|
||||
const cellVal = (i: number): string => {
|
||||
const cell = cells[i];
|
||||
if (!cell) return '';
|
||||
// Prefer input value, then select text, then textContent
|
||||
const input = cell.querySelector('input[type="text"], input:not([type])') as HTMLInputElement | null;
|
||||
if (input) return input.value?.trim() ?? '';
|
||||
const select = cell.querySelector('select') as HTMLSelectElement | null;
|
||||
@@ -781,7 +786,7 @@ async function scrapeMemberFahrgenehmigungen(frame: Frame, standesbuchNr: string
|
||||
log(` ${f.ausstellungsdatum ?? '—'} [${f.klasse}] ${f.behoerde ?? ''} ${f.nummer ?? ''}`);
|
||||
}
|
||||
} catch {
|
||||
log(` WARN: could not parse Fahrgenehmigungen table for StNr ${standesbuchNr}`);
|
||||
log(` WARN: could not parse Fahrgenehmigungen table for StNr ${standesbuchNr} (url: ${url})`);
|
||||
}
|
||||
|
||||
return results;
|
||||
|
||||
Reference in New Issue
Block a user