- Per generare la sinossi è possibile estrarre con 1 click la descrizione sia da Amazon che da GruppoMacro.
- corretto piccolo bug sul catalogo.
This commit is contained in:
99
src/server/models/myscrapingbook.js
Executable file
99
src/server/models/myscrapingbook.js
Executable file
@@ -0,0 +1,99 @@
|
||||
const mongoose = require('mongoose').set('debug', false);
|
||||
const Schema = mongoose.Schema;
|
||||
|
||||
const tools = require('../tools/general');
|
||||
|
||||
mongoose.Promise = global.Promise;
|
||||
mongoose.level = 'F';
|
||||
|
||||
// Resolving error Unknown modifier: $pushAll
|
||||
mongoose.plugin((schema) => {
|
||||
schema.options.usePushEach = true;
|
||||
});
|
||||
|
||||
const MyScrapingBookSchema = new Schema({
|
||||
isbn: {
|
||||
type: String,
|
||||
index: true,
|
||||
},
|
||||
isbn10: {
|
||||
type: String,
|
||||
},
|
||||
fonte: {
|
||||
type: String,
|
||||
},
|
||||
titolo: {
|
||||
type: String,
|
||||
},
|
||||
titoloOriginale: {
|
||||
type: String,
|
||||
},
|
||||
sottotitolo: {
|
||||
type: String,
|
||||
},
|
||||
autore: {
|
||||
type: String,
|
||||
},
|
||||
pagine: {
|
||||
type: String,
|
||||
},
|
||||
misure: {
|
||||
type: String,
|
||||
},
|
||||
edizione: {
|
||||
type: String,
|
||||
},
|
||||
editore: {
|
||||
type: String,
|
||||
},
|
||||
date_pub: {
|
||||
type: Date,
|
||||
},
|
||||
url: {
|
||||
type: String,
|
||||
},
|
||||
stelline: {
|
||||
type: Number,
|
||||
},
|
||||
prezzo: {
|
||||
type: String,
|
||||
},
|
||||
date_extraction: {
|
||||
type: Date,
|
||||
},
|
||||
descrizione_lunga: {
|
||||
type: String,
|
||||
},
|
||||
});
|
||||
|
||||
MyScrapingBookSchema.statics.getFieldsForSearch = function () {
|
||||
return [{ field: 'titolo', type: tools.FieldType.string }];
|
||||
};
|
||||
|
||||
MyScrapingBookSchema.statics.executeQueryTable = function (idapp, params, user) {
|
||||
params.fieldsearch = this.getFieldsForSearch();
|
||||
return tools.executeQueryTable(this, idapp, params, user);
|
||||
};
|
||||
|
||||
MyScrapingBookSchema.statics.findAllIdApp = async function (idapp) {
|
||||
const MyScrapingBook = this;
|
||||
|
||||
const myfind = { idapp };
|
||||
|
||||
try {
|
||||
return await MyScrapingBook.find(myfind).sort({ titolo: 1 }).lean();
|
||||
} catch (err) {
|
||||
console.error('Errore in MyScrapingBook:', err, model);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const MyScrapingBook = mongoose.model('MyScrapingBook', MyScrapingBookSchema);
|
||||
|
||||
MyScrapingBook.createIndexes()
|
||||
.then(() => {})
|
||||
.catch((err) => {
|
||||
throw err;
|
||||
});
|
||||
|
||||
module.exports = { MyScrapingBook };
|
||||
@@ -494,7 +494,7 @@ module.exports.findAllIdApp = async function (idapp, code, id, all, isbn) {
|
||||
myfind = { ...myfind, code };
|
||||
}
|
||||
if (isbn) {
|
||||
myfind = { ...myfind, sbn };
|
||||
myfind = { ...myfind, isbn };
|
||||
}
|
||||
if (id) {
|
||||
myqueryadd = {
|
||||
|
||||
@@ -57,7 +57,10 @@ class CronMod {
|
||||
// } else if (mydata.dbop === 'rigeneraTutto') {
|
||||
// await ListaIngresso.Esegui_CronTab(idapp, mydata);
|
||||
} else if (mydata.dbop === "ScraperMultipleDataAmazon") {
|
||||
mystr = await AmazonBookScraper.ScraperMultipleDataAmazon(idapp, mydata.options);
|
||||
mystr = await AmazonBookScraper.ScraperMultipleDataAmazon(idapp, {update: true, aggiornasoloSeVuoti: true, forzaricarica: false});
|
||||
ris = { mystr };
|
||||
} else if (mydata.dbop === "ScraperMultipleDataDBStored") {
|
||||
mystr = await AmazonBookScraper.ScraperMultipleDataDBStored(idapp, {update: true, aggiornasoloSeVuoti: true, forzaricarica: false, dbstored: true});
|
||||
ris = { mystr };
|
||||
} else if (mydata.dbop === "ScraperGeneraCSV") {
|
||||
mystr = await AmazonBookScraper.ScraperGeneraCSV(idapp, mydata.options, res);
|
||||
|
||||
@@ -9,32 +9,76 @@ const shared_consts = require('../tools/shared_nodejs');
|
||||
|
||||
const fs = require('fs').promises; // 👈 Usa il modulo promises
|
||||
|
||||
const { MyScrapingBook } = require('../models/myscrapingbook');
|
||||
|
||||
class AmazonBookScraper {
|
||||
constructor() {
|
||||
this.baseUrl = 'https://www.amazon.it/dp/';
|
||||
}
|
||||
|
||||
async fetchPageISBN10(isbn10) {
|
||||
getUserAgentRandom() {
|
||||
// Lista di User-Agent comuni per i vari browser
|
||||
const userAgents = [
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Edge/91.0.864.59 Safari/537.36',
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
|
||||
'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0',
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:80.0) Gecko/20100101 Firefox/80.0',
|
||||
'Mozilla/5.0 (Windows NT 6.1; Trident/7.0; AS; rv:11.0) like Gecko',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36',
|
||||
'Mozilla/5.0 (Windows NT 6.1; rv:56.0) Gecko/20100101 Firefox/56.0',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36',
|
||||
];
|
||||
|
||||
// Seleziona un User-Agent casuale dalla lista
|
||||
const randomIndex = Math.floor(Math.random() * userAgents.length);
|
||||
return userAgents[randomIndex];
|
||||
}
|
||||
|
||||
async fetchPageISBN10(isbn10, isbn) {
|
||||
if (!isbn10) return false;
|
||||
|
||||
const url = `${this.baseUrl}${isbn10}`;
|
||||
try {
|
||||
const { data } = await axios.get(url, {
|
||||
headers: {
|
||||
'User-Agent':
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ' +
|
||||
'AppleWebKit/537.36 (KHTML, like Gecko) ' +
|
||||
'Chrome/113.0.0.0 Safari/537.36',
|
||||
// altri header se necessario
|
||||
},
|
||||
});
|
||||
return { html: data, url };
|
||||
} catch (err) {
|
||||
console.error(`Errore fetching ISBN ${isbn10}:`, err.message);
|
||||
return null;
|
||||
const retryLimit = 2; // Numero massimo di tentativi
|
||||
const timeout = 7000; // Timeout di 5 secondi per la richiesta
|
||||
const delay = 10000; // Ritardo tra i tentativi (10 secondi)
|
||||
|
||||
for (let attempt = 1; attempt <= retryLimit; attempt++) {
|
||||
try {
|
||||
const { data } = await axios.get(url, {
|
||||
headers: {
|
||||
'User-Agent': this.getUserAgentRandom(),
|
||||
// Aggiungi altri header se necessario
|
||||
},
|
||||
timeout, // Timeout di 5 secondi per la richiesta
|
||||
});
|
||||
return { html: data, url };
|
||||
} catch (err) {
|
||||
console.error(`Errore fetching isbn10 ${isbn10} (ISBN:${isbn}) (tentativo ${attempt}):`, err.message);
|
||||
|
||||
if (attempt < retryLimit) {
|
||||
console.log(`Riprovo tra ${delay / 1000} secondi...`);
|
||||
await new Promise((resolve) => setTimeout(resolve, delay)); // Ritardo prima di riprovare
|
||||
} else {
|
||||
console.error(
|
||||
`Impossibile recuperare la pagina per ISBN10 ${isbn10} (ISBN:${isbn}) dopo ${retryLimit} tentativi.`
|
||||
);
|
||||
await Product.findOneAndUpdate(
|
||||
{ isbn: isbn },
|
||||
{ $set: { scraped: true, scraped_error: true } },
|
||||
{ upsert: true, new: true, includeResultMetadata: true }
|
||||
).lean();
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
isbn13to10(isbn13) {
|
||||
try {
|
||||
if (!isbn13.startsWith('978') || isbn13.length !== 13) return null;
|
||||
if (!(isbn13.startsWith('978') || isbn13.startsWith('979')) || isbn13.length !== 13) return null;
|
||||
|
||||
const core = isbn13.slice(3, 12); // i 9 numeri centrali
|
||||
|
||||
let sum = 0;
|
||||
@@ -60,7 +104,7 @@ class AmazonBookScraper {
|
||||
}
|
||||
}
|
||||
|
||||
async extractData(myproduct, html, url) {
|
||||
async extractData(myproduct, html, url, isbn10) {
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
const productInfo = await ProductInfo.findOne({ _id: myproduct.idProductInfo }).lean();
|
||||
@@ -94,11 +138,19 @@ class AmazonBookScraper {
|
||||
let edizione = null;
|
||||
let publisher = null;
|
||||
let data_pubblicazione = null;
|
||||
let descrizione_lunga = null;
|
||||
let prezzo = null;
|
||||
let stelline = null;
|
||||
let autore = null;
|
||||
|
||||
numpagine = this.extractNumeroDiPagine($);
|
||||
const dim = this.extractDimensions($);
|
||||
misure = this.convertDimensionsToMisureMacro(dim);
|
||||
const data_pubb = this.extractDataPubblicazione($);
|
||||
descrizione_lunga = this.extractDescrizioneLunga($);
|
||||
autore = this.extractAutore($);
|
||||
stelline = this.extractStelline($);
|
||||
prezzo = this.extractPrezzo($);
|
||||
data_pubblicazione = this.parseItalianDate(data_pubb);
|
||||
|
||||
publisher = this.extractEditore($);
|
||||
@@ -107,39 +159,121 @@ class AmazonBookScraper {
|
||||
edizione = this.extractMonthYear(data_pubb);
|
||||
}
|
||||
|
||||
return {
|
||||
const fonte = 'AMAZON';
|
||||
|
||||
const data = {
|
||||
isbn: myproduct.isbn,
|
||||
isbn10,
|
||||
titolo: title,
|
||||
fonte,
|
||||
...(titoloOriginale ? { titoloOriginale } : {}),
|
||||
...(sottotitolo ? { sottotitolo } : { sottotitolo: '' }),
|
||||
...(autore ? { autore } : { autore: '' }),
|
||||
...(stelline ? { stelline } : {}),
|
||||
...(numpagine ? { numpagine } : {}),
|
||||
...(misure ? { misure } : {}),
|
||||
...(edizione ? { edizione } : {}),
|
||||
...(data_pubblicazione ? { data_pubblicazione } : {}),
|
||||
...(descrizione_lunga ? { descrizione_lunga } : {}),
|
||||
...(publisher ? { editore: publisher } : {}),
|
||||
url: `<a href="${url}" target="_blank">URL</a>`,
|
||||
url: `<a href="${url}" target="_blank">VAI AL SITO ${fonte}</a>`,
|
||||
...(data_pubblicazione ? { data_pubblicazione } : {}),
|
||||
...(prezzo ? { prezzo } : {}),
|
||||
};
|
||||
|
||||
// Aggiungilo al record
|
||||
await this.addOrUpdateMyScrapingBook(data);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
async findRecordMyScrapingBookByIsbn(isbn) {
|
||||
const record = await MyScrapingBook.findOne({ isbn }).lean();
|
||||
return record;
|
||||
}
|
||||
|
||||
async addOrUpdateMyScrapingBook(data) {
|
||||
try {
|
||||
const {
|
||||
isbn,
|
||||
isbn10,
|
||||
titolo,
|
||||
titoloOriginale,
|
||||
fonte,
|
||||
url,
|
||||
sottotitolo,
|
||||
autore,
|
||||
numpagine,
|
||||
misure,
|
||||
edizione,
|
||||
editore,
|
||||
data_pubblicazione,
|
||||
stelline,
|
||||
prezzo,
|
||||
descrizione_lunga,
|
||||
} = data;
|
||||
|
||||
// Cerca un record esistente per ISBN
|
||||
let record = await MyScrapingBook.findOne({ isbn }).lean();
|
||||
|
||||
// Se il record esiste, aggiorna i campi
|
||||
await MyScrapingBook.updateOne(
|
||||
{ isbn },
|
||||
{
|
||||
$set: {
|
||||
isbn10,
|
||||
titolo,
|
||||
fonte,
|
||||
titoloOriginale,
|
||||
sottotitolo,
|
||||
autore,
|
||||
pagine: numpagine,
|
||||
misure,
|
||||
edizione,
|
||||
editore,
|
||||
date_pub: data_pubblicazione,
|
||||
url,
|
||||
stelline,
|
||||
prezzo,
|
||||
descrizione_lunga,
|
||||
date_extraction: new Date(),
|
||||
},
|
||||
},
|
||||
{ upsert: true }
|
||||
);
|
||||
} catch (err) {
|
||||
console.error('Errore gestendo MyScrapingBook:', err);
|
||||
}
|
||||
}
|
||||
|
||||
async scrapeISBN(myproduct, isbn, options) {
|
||||
try {
|
||||
const isbn10 = this.isbn13to10(isbn);
|
||||
const res = await this.fetchPageISBN10(isbn10);
|
||||
if (!res) {
|
||||
await Product.findOneAndUpdate(
|
||||
{ _id: myproduct._id },
|
||||
{ $set: { scraped: true, scraped_error: true } },
|
||||
{ upsert: true, new: true, includeResultMetadata: true }
|
||||
).lean();
|
||||
const datastored = await this.findRecordMyScrapingBookByIsbn(isbn);
|
||||
|
||||
return null;
|
||||
}
|
||||
const html = res.html;
|
||||
if (!html) return null;
|
||||
let data = null;
|
||||
|
||||
let updated = null;
|
||||
let risupdate = null;
|
||||
|
||||
const data = await this.extractData(myproduct, html, res.url);
|
||||
// prima cerca sulla tabella che ho scaricato
|
||||
if (options.forzaricarica || !datastored) {
|
||||
const isbn10 = this.isbn13to10(isbn);
|
||||
const res = await this.fetchPageISBN10(isbn10, isbn);
|
||||
if (!res) {
|
||||
await Product.findOneAndUpdate(
|
||||
{ _id: myproduct._id },
|
||||
{ $set: { scraped: true, scraped_error: true } },
|
||||
{ upsert: true, new: true, includeResultMetadata: true }
|
||||
).lean();
|
||||
|
||||
return null;
|
||||
}
|
||||
const html = res.html;
|
||||
if (!html) return null;
|
||||
|
||||
data = await this.extractData(myproduct, html, res.url, isbn10);
|
||||
} else {
|
||||
data = { ...datastored };
|
||||
}
|
||||
|
||||
if (!options?.update) return data;
|
||||
|
||||
@@ -233,7 +367,7 @@ class AmazonBookScraper {
|
||||
{ $set: { scraped: true, scraped_date: new Date() } },
|
||||
{ upsert: true, new: true, returnDocument: 'after' }
|
||||
);
|
||||
console.log('upd', upd);
|
||||
// console.log('upd', upd);
|
||||
}
|
||||
|
||||
if (aggiornaProductInfo) {
|
||||
@@ -293,13 +427,15 @@ class AmazonBookScraper {
|
||||
if (!arrvar.misure) {
|
||||
datimancanti = true;
|
||||
}
|
||||
if (!arrvar.edizione) {
|
||||
/*if (!arrvar.edizione) {
|
||||
datimancanti = true;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
if (product.idProductInfo) {
|
||||
if (!tools.isDateValid(product.idProductInfo.date_pub)) datimancanti = true;
|
||||
if (!tools.isDateValid(product.idProductInfo.date_pub)) {
|
||||
datimancanti = true;
|
||||
}
|
||||
}
|
||||
|
||||
return datimancanti;
|
||||
@@ -333,7 +469,7 @@ class AmazonBookScraper {
|
||||
console.log(`scrapeMultiple INIZIATO...`);
|
||||
let dataorainizio = new Date();
|
||||
|
||||
for (let i = 0; i < 100 && i < products.length; i++) {
|
||||
for (let i = 0; i < products.length; i++) {
|
||||
const product = products[i];
|
||||
let isbn = product.isbn;
|
||||
|
||||
@@ -348,7 +484,7 @@ class AmazonBookScraper {
|
||||
}
|
||||
|
||||
if (i % 1 === 0) {
|
||||
const percentuale = ((quanti / products.length) * 100).toFixed(2);
|
||||
const percentuale = ((i / products.length) * 100).toFixed(2);
|
||||
console.log(
|
||||
`Scraping: ${product.isbn} - ${product.idProductInfo.name} - ${quanti} su ${i + 1} / ${
|
||||
products.length
|
||||
@@ -357,10 +493,11 @@ class AmazonBookScraper {
|
||||
}
|
||||
|
||||
// Per evitare blocchi, metti una pausa (es. 2 secondi)
|
||||
await new Promise((r) => setTimeout(r, 3000));
|
||||
await new Promise((r) => setTimeout(r, 2000));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mylog += `RECORD AGGIORNATI: ${results.length - 1} su ${quanti}`;
|
||||
return results;
|
||||
}
|
||||
@@ -389,6 +526,12 @@ class AmazonBookScraper {
|
||||
await Product.updateMany({ idapp, scraped_updated: true }, { $set: { scraped_updated: false } });
|
||||
}
|
||||
|
||||
static async ScraperAzzeraFlagErrori(idapp, options) {
|
||||
// aggiorna tutti i record di Product (con idapp) scraped: false
|
||||
|
||||
await Product.updateMany({ idapp, scraped_error: true }, { $set: { scraped: false } });
|
||||
}
|
||||
|
||||
static async removeDuplicateVariations(idapp, options) {
|
||||
let mylog = 'removeDuplicateVariations...\n';
|
||||
|
||||
@@ -478,7 +621,6 @@ class AmazonBookScraper {
|
||||
.populate({ path: 'idProductInfo', select: 'date_pub name sottotitolo' })
|
||||
.lean();
|
||||
|
||||
|
||||
// Funzione per "appiattire" i dati
|
||||
const flattenData = (data) => {
|
||||
return data.map((item) => {
|
||||
@@ -565,8 +707,9 @@ class AmazonBookScraper {
|
||||
idapp,
|
||||
isbn: { $exists: true, $ne: '' },
|
||||
scraped: { $ne: true }, // Escludi direttamente i record con scraped = true
|
||||
$or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }],
|
||||
$or: [{ scraped_error: { $exists: false } }, { scraped_error: { $exists: true, $eq: false } }],
|
||||
/*$or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }],
|
||||
*/
|
||||
},
|
||||
},
|
||||
// Popoliamo il campo idProductInfo
|
||||
@@ -622,31 +765,131 @@ class AmazonBookScraper {
|
||||
}
|
||||
|
||||
extractDataPubblicazione($) {
|
||||
// Seleziona il div con id specifico per la data di pubblicazione
|
||||
const publicationDate = $('#rpi-attribute-book_details-publication_date .rpi-attribute-value span').text().trim();
|
||||
try {
|
||||
// Seleziona il div con id specifico per la data di pubblicazione
|
||||
const publicationDate = $('#rpi-attribute-book_details-publication_date .rpi-attribute-value span').text().trim();
|
||||
|
||||
// Se non trova la data, ritorna null
|
||||
return publicationDate || null;
|
||||
// Se non trova la data, ritorna null
|
||||
return publicationDate || null;
|
||||
} catch (error) {
|
||||
console.error('Error extracting publication date:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
extractDescrizioneLunga($) {
|
||||
try {
|
||||
// Cerca l'elemento che contiene la descrizione lunga
|
||||
const descriptionElement = $('#bookDescription_feature_div .a-expander-content span');
|
||||
|
||||
// Estrai il testo e rimuovi eventuali spazi extra o tag HTML
|
||||
const description = descriptionElement.text().trim();
|
||||
|
||||
// Se la descrizione è vuota, restituisci null
|
||||
return description || null;
|
||||
} catch (error) {
|
||||
console.error('Error extracting long description:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
extractAutore($) {
|
||||
try {
|
||||
// Seleziona tutti gli elementi che contengono gli autori
|
||||
const authorsElements = $('#bylineInfo .author a');
|
||||
|
||||
// Estrai il testo per ogni autore e rimuovi spazi extra
|
||||
const authors = authorsElements.map((i, el) => $(el).text().trim()).get();
|
||||
|
||||
// Se ci sono autori, restituiscili come stringa separata da virgole
|
||||
return authors.length > 0 ? authors.join(', ') : null;
|
||||
} catch (error) {
|
||||
console.error('Error extracting authors:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
extractStelline($) {
|
||||
try {
|
||||
// Cerca l'elemento che contiene la descrizione lunga
|
||||
// Seleziona l'elemento che contiene il voto medio (5,0 su 5 stelle)
|
||||
const ratingText = $('#acrPopover').attr('title');
|
||||
|
||||
if (ratingText) {
|
||||
// Estrai il numero di stelle dal testo "5,0 su 5 stelle"
|
||||
const stars = ratingText.split(' su ')[0].replace(',', '.'); // Cambia la virgola in punto
|
||||
return stars; // Restituisce il numero di stelle
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error extracting stars:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
extractPrezzo($) {
|
||||
try {
|
||||
// Seleziona l'elemento che contiene il prezzo
|
||||
const priceElement = $(
|
||||
'.a-box-group .a-section #desktop_qualifiedBuyBox #corePriceDisplay_desktop_feature_div .a-price .a-price-whole'
|
||||
);
|
||||
|
||||
// Estrai il prezzo principale e la parte decimale
|
||||
const wholePrice = priceElement.text().trim();
|
||||
const decimalPrice = $(
|
||||
'.a-box-group .a-section #desktop_qualifiedBuyBox #corePriceDisplay_desktop_feature_div .a-price .a-price-fraction'
|
||||
)
|
||||
.text()
|
||||
.trim();
|
||||
|
||||
// Estrai il simbolo della valuta
|
||||
const currencySymbol = $(
|
||||
'.a-box-group .a-section #desktop_qualifiedBuyBox #corePriceDisplay_desktop_feature_div .a-price .a-price-symbol'
|
||||
)
|
||||
.text()
|
||||
.trim();
|
||||
|
||||
// Se il prezzo è stato trovato, formattalo come prezzo completo
|
||||
if (wholePrice && decimalPrice && currencySymbol) {
|
||||
const fullPrice = `${wholePrice}${decimalPrice} ${currencySymbol}`;
|
||||
return fullPrice;
|
||||
}
|
||||
|
||||
// Se non trova il prezzo, restituisce null
|
||||
return null;
|
||||
} catch (error) {
|
||||
console.error('Error extracting price:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
extractNumeroDiPagine($) {
|
||||
// Seleziona il div con id specifico per pagine
|
||||
const pagesText = $('#rpi-attribute-book_details-fiona_pages .rpi-attribute-value span').text().trim();
|
||||
try {
|
||||
// Seleziona il div con id specifico per pagine
|
||||
const pagesText = $('#rpi-attribute-book_details-fiona_pages .rpi-attribute-value span').text().trim();
|
||||
|
||||
// pagesText dovrebbe essere tipo "184 pagine"
|
||||
if (!pagesText) return null;
|
||||
// pagesText dovrebbe essere tipo "184 pagine"
|
||||
if (!pagesText) return null;
|
||||
|
||||
// Estrai solo il numero (facoltativo)
|
||||
const match = pagesText.match(/(\d+)/);
|
||||
return match ? match[1] : pagesText; // ritorna solo il numero o il testo intero
|
||||
// Estrai solo il numero (facoltativo)
|
||||
const match = pagesText.match(/(\d+)/);
|
||||
return match ? match[1] : pagesText; // ritorna solo il numero o il testo intero
|
||||
} catch (error) {
|
||||
console.error('Error extracting number of pages:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
extractDimensions($) {
|
||||
// Seleziona il div con id specifico per dimensioni
|
||||
const dimText = $('#rpi-attribute-book_details-dimensions .rpi-attribute-value span').text().trim();
|
||||
try {
|
||||
// Seleziona il div con id specifico per dimensioni
|
||||
const dimText = $('#rpi-attribute-book_details-dimensions .rpi-attribute-value span').text().trim();
|
||||
|
||||
// Se non trova niente ritorna null
|
||||
return dimText || null;
|
||||
// Se non trova niente ritorna null
|
||||
return dimText || null;
|
||||
} catch (error) {
|
||||
console.error('Error extracting dimensions:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
convertDimensionsToMisureMacro(dimString) {
|
||||
|
||||
@@ -27,7 +27,7 @@ const Gasordine = require('../models/gasordine');
|
||||
|
||||
const { User } = require('../models/user');
|
||||
|
||||
const AmazonBookScraper = require('../modules/scraping');
|
||||
const AmazonBookScraper = require('../modules/Scraping');
|
||||
|
||||
const { Catalog } = require('../models/catalog');
|
||||
const { RaccoltaCataloghi } = require('../models/raccoltacataloghi');
|
||||
|
||||
@@ -22,7 +22,7 @@ router.post('/', auth_default, async function (req, res, next) {
|
||||
|
||||
let ismanager = await tools.isManagerByReq(req);
|
||||
|
||||
let catalogs = await Catalog.findAllIdApp(idapp, '', undefined, ismanager);
|
||||
let catalogs = await Catalog.findAllIdApp(idapp);
|
||||
let orders = null;
|
||||
|
||||
if (catalogs) return res.send({ code: server_constants.RIS_CODE_OK, catalogs, orders });
|
||||
|
||||
57
src/server/router/myscraping_router.js
Executable file
57
src/server/router/myscraping_router.js
Executable file
@@ -0,0 +1,57 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
|
||||
const tools = require('../tools/general');
|
||||
|
||||
var server_constants = require('../tools/server_constants');
|
||||
|
||||
const { User } = require('../models/user');
|
||||
|
||||
var { authenticate, auth_default } = require('../middleware/authenticate');
|
||||
|
||||
const _ = require('lodash');
|
||||
|
||||
const { MyScrapingBook } = require('../models/myscrapingbook');
|
||||
const Product = require('../models/product');
|
||||
|
||||
const AmazonBookScraper = require('../modules/Scraping');
|
||||
|
||||
//GET /products
|
||||
router.post('/', auth_default, async function (req, res, next) {
|
||||
const idapp = req.body.idapp;
|
||||
const isbn = req.body.isbn;
|
||||
const forzacaricamento = req.body.forzacaricamento;
|
||||
|
||||
try {
|
||||
let myscraping = null;
|
||||
if (isbn) {
|
||||
myscraping = await MyScrapingBook.findOne({ isbn }).lean();
|
||||
|
||||
if (!myscraping && forzacaricamento) {
|
||||
const scraper = new AmazonBookScraper();
|
||||
|
||||
const options = {
|
||||
update: false,
|
||||
forzaricarica: false,
|
||||
};
|
||||
|
||||
const myproduct = await Product.getProductByIsbn(idapp, isbn);
|
||||
if (myproduct && myproduct.length > 0) {
|
||||
myscraping = await scraper.scrapeISBN(myproduct[0], isbn, options);
|
||||
// console.log(myscraping);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (myscraping) {
|
||||
return res.send({ code: server_constants.RIS_CODE_OK, myscraping });
|
||||
} else {
|
||||
return res.send({ code: server_constants.RIS_CODE_OK, myscraping: null });
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
return res.status(400).send({ code: server_constants.RIS_CODE_ERR, msg: e.message });
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
@@ -128,6 +128,7 @@ connectToDatabase(connectionUrl, options)
|
||||
const site_router = require('./router/site_router');
|
||||
const admin_router = require('./router/admin_router');
|
||||
const products_router = require('./router/products_router');
|
||||
const myscraping_router = require('./router/myscraping_router');
|
||||
const catalogs_router = require('./router/catalogs_router');
|
||||
const cart_router = require('./router/cart_router');
|
||||
const orders_router = require('./router/orders_router');
|
||||
@@ -238,6 +239,7 @@ connectToDatabase(connectionUrl, options)
|
||||
app.use('/site', site_router);
|
||||
app.use('/admin', admin_router);
|
||||
app.use('/products', products_router);
|
||||
app.use('/myscraping', myscraping_router);
|
||||
app.use('/catalogs', catalogs_router);
|
||||
app.use('/cart', cart_router);
|
||||
app.use('/orders', orders_router);
|
||||
|
||||
@@ -48,6 +48,7 @@ const Pickup = require('../models/pickup');
|
||||
const { Newstosent } = require('../models/newstosent');
|
||||
const { MyPage } = require('../models/mypage');
|
||||
const { MyElem } = require('../models/myelem');
|
||||
const { MyScrapingBook } = require('../models/myscrapingbook');
|
||||
const { Cron } = require('../models/cron');
|
||||
const { MyScheda } = require('../models/myscheda');
|
||||
const { MyBot } = require('../models/bot');
|
||||
@@ -200,6 +201,8 @@ module.exports = {
|
||||
mytable = MyPage;
|
||||
else if (tablename === 'myelems')
|
||||
mytable = MyElem;
|
||||
else if (tablename === 'myscrapingbooks')
|
||||
mytable = MyScrapingBook;
|
||||
else if (tablename === 'crons')
|
||||
mytable = Cron;
|
||||
else if (tablename === 'myschedas')
|
||||
|
||||
@@ -1 +1 @@
|
||||
1.2.47
|
||||
1.2.48
|
||||
Reference in New Issue
Block a user