Files
fredy/lib/services/extractor/parser/parser.js

104 lines
2.6 KiB
JavaScript
Raw Normal View History

2025-12-11 10:40:55 +01:00
/*
* Copyright (c) 2025 by Christian Kellner.
* Licensed under Apache-2.0 with Commons Clause and Attribution/Naming Clause
*/
import * as cheerio from 'cheerio';
2025-09-13 18:57:56 +02:00
import logger from '../../logger.js';
let $ = null;
export function loadParser(text) {
2025-01-07 12:25:19 +01:00
$ = cheerio.load(text);
}
2025-01-07 12:25:19 +01:00
export function parse(crawlContainer, crawlFields, text, url) {
if (!text) {
logger.debug('No content found for ', url);
2025-01-07 12:25:19 +01:00
return null;
}
if (!crawlContainer || !crawlFields) {
logger.debug('Cannot parse, selector was empty for url ', url);
2025-01-07 12:25:19 +01:00
return null;
}
const result = [];
if ($(crawlContainer).length === 0) {
logger.debug('No elements in crawl container found for url ', url);
return null;
2025-01-07 12:25:19 +01:00
}
$(crawlContainer).each((_, element) => {
const container = $(element);
const parsedObject = {};
// Parse fields based on crawlFields
for (const [key, fieldSelector] of Object.entries(crawlFields)) {
let value;
try {
const selector = fieldSelector.includes('|')
? fieldSelector.substring(0, fieldSelector.indexOf('|')).trim()
: fieldSelector;
if (selector.includes('@')) {
const [sel, attr] = selector.split('@');
if (sel.length === 0) {
value = container.attr(attr.trim());
} else {
value = container.find(sel.trim()).attr(attr.trim());
}
} else {
value = container.find(selector.trim()).text();
}
2025-01-07 12:25:19 +01:00
// Apply modifiers if specified
if (fieldSelector.includes('|')) {
/* eslint-disable no-unused-vars */
const [_, ...modifiers] = fieldSelector.split('|').map((s) => s.trim());
2025-08-31 20:09:38 +02:00
/* eslint-enable no-unused-vars */
2025-01-07 12:25:19 +01:00
value = applyModifiers(value, modifiers);
}
2025-01-07 12:25:19 +01:00
parsedObject[key] = value || null;
} catch (error) {
2025-09-13 18:57:56 +02:00
logger.error(`Error parsing field '${key}' with selector '${fieldSelector}':`, error);
2025-01-07 12:25:19 +01:00
parsedObject[key] = null;
}
}
2025-01-07 12:25:19 +01:00
if (parsedObject.id != null) {
result.push(parsedObject);
} else {
2025-09-13 18:57:56 +02:00
logger.debug('ID not found. Not relaying object.');
2025-01-07 12:25:19 +01:00
}
});
2025-01-07 12:25:19 +01:00
return result;
}
// Helper function to apply modifiers
function applyModifiers(value, modifiers) {
2025-01-07 12:25:19 +01:00
if (!value) return value;
modifiers.forEach((modifier) => {
switch (modifier) {
case 'int':
value = parseInt(value, 10);
break;
case 'trim':
value = value.replace(/\s+/g, ' ').trim();
break;
case 'removeNewline':
value = value.replace(/\n/g, ' ');
break;
default:
2025-09-13 18:57:56 +02:00
logger.warn(`Unknown modifier: ${modifier}`);
2025-01-07 12:25:19 +01:00
}
});
2025-01-07 12:25:19 +01:00
return value;
}