Selector para alegre (Node.js) trabajando en consola pero no en mi script

Estoy escribiendo un sencillo script para raspar una tabla de divisas de un sitio web.

Este es mi guión hasta ahora y lo que quiero hacer es conseguir la tabla de tasas de FOREX de este sitio web: https://www.bangkokbank.com/en/Personal/Other-Services/View-Rates/Foreign-Exchange-Rates

Este es mi código hasta ahora.

const cheerio = require('cheerio');
const request = require('request');

request({
    method: 'GET',
    url: 'https://www.bangkokbank.com/en/Personal/Other-Services/View-Rates/Foreign-Exchange-Rates'
}, (err, res, body) => {

    if (err) return console.error(err);
    let $ = cheerio.load(body);
    var x = [];
    var hello = $("#exchange-rates > div.table-outer > table > tbody> tr > td");
    
    console.log(hello);


    $("#exchange-rates > div.table-outer > table > tbody> tr > td").each((i, elem) => {
        x.push($(elem).text());
        console.log($(elem).text());
    });
    
});

Cuando ejecuto "$("#exchange-rates √≥ div.table-outer √Īo tabla нелино tbody título tr нно td")" en la consola en la página web (haciendo clic en la inspección), es capaz de identificar todos los elementos relevantes. Pero no está recibiendo nada cuando ejecuto el script en JavaScript.

¿Puede alguien aconsejar? ¡Gracias!

Pregunta hecha hace 3 años, 4 meses, 28 días - Por codemaster89


3 Respuestas:

  • El camino dado no existe en el sitio web estático. Este sitio web transmite el contenido dinámicamente, es decir, una vez que el contenido web se entrega en el navegador, se realiza una manipulación DOM para renderizar datos. Así que la página web estática sólo tiene "#exchange-rates > div.table-outer > table > tbody. El tr, td las etiquetas se adjuntan una vez que se recoge en el navegador. Usted puede tener que ver cualquier otra solución alternativa para obtener los tipos de cambio de forex, digamos utilizando cualquier API existente.

    Respondida el Dec 18, 2020 a las 04:20 - por apiartisan

    Votos positivos: 0 | Votos negativos: 0

  • El problema que estás experimentando podría deberse a que el script está ejecutándose antes de que la página haya cargado completamente y la información que intentas raspar aún no está disponible en el DOM al momento de la ejecución de tu script.

    Para resolver esto, puedes intentar usar una librería como 'puppeteer' en lugar de 'request' para cargar la página de manera dinámica y esperar a que todos los elementos necesario estén disponibles antes de intentar raspar la información.

    Aquí te dejo un ejemplo modificado de tu script utilizando 'puppeteer':

    javascript
    const cheerio = require('cheerio');
    const puppeteer = require('puppeteer');
    
    (async () => {
        const browser = await puppeteer.launch();
        const page = await browser.newPage();
    
        await page.goto('https://www.bangkokbank.com/en/Personal/Other-Services/View-Rates/Foreign-Exchange-Rates');
    
        const content = await page.content();
        let $ = cheerio.load(content);
    
        var x = [];
    
        $("exchange-rates > div.table-outer > table > tbody > tr > td").each((i, elem) => {        x.push($(elem).text());
            console.log($(elem).text());
        });
    
        await browser.close();
    })();
    

    Este script abrirá un navegador controlado por 'puppeteer', cargará la página indicada y luego raspará la información de la tabla de tasas de cambio una vez que todos los elementos estén disponibles en el DOM.

    Asegúrate de instalar la librería 'puppeteer' antes de ejecutar el script:

    
    npm install puppeteer
    

    ¡Espero que esta solución te ayude a resolver el problema! ¡Déjame saber si necesitas ayuda adicional!

    Respondida el Dec 19, 2020 a las 04:19 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Existen algunas diferencias clave entre ejecutar el selector en la consola del navegador y en un script de Node.js.

    Contexto del documento

    En la consola del navegador, el contexto del documento es la página web que estás viendo actualmente. Esto significa que el selector "$("<h15>exchange-rates > div.table-outer > table > tbody> tr > td")" se ejecuta en el contexto de la página web de Bangkok Bank. En un script de Node.js, el contexto del documento es el contenido HTML que has cargado usando la biblioteca request. Esto significa que el selector se ejecuta en el contexto del HTML cargado, que puede no ser exactamente el mismo que el HTML de la página web.

    Carga asíncrona

    La biblioteca request carga el HTML de forma asíncrona, lo que significa que el callback proporcionado se invoca cuando el HTML se ha cargado completamente. Esto puede provocar problemas si intentas ejecutar el selector antes de que se haya cargado el HTML.

    Para resolver estos problemas, asegúrate de lo siguiente:

    Verifica que el HTML se haya cargado completamente: Puedes hacer esto comprobando si el objeto res tiene un código de estado 200 (OK) antes de cargar el HTML. Usa una función de devolución de llamada: Envuelve el selector en una función de devolución de llamada que se invoca después de que se haya cargado el HTML. Esto garantiza que el selector se ejecute en el contexto del HTML cargado.

    Aquí tienes un código actualizado que aborda estos problemas:

    javascript
    const cheerio = require('cheerio');
    const request = require('request');
    
    request({
        method: 'GET',
        url: 'https://www.bangkokbank.com/en/Personal/Other-Services/View-Rates/Foreign-Exchange-Rates'
    }, (err, res, body) => {
    
        if (err || res.statusCode !== 200) return console.error(err);
    
        let $ = cheerio.load(body);
        var x = [];
    
        $("exchange-rates > div.table-outer > table > tbody> tr > td").each((i, elem) => {        x.push($(elem).text());
            console.log($(elem).text());
        });
    });
    

    Con estos cambios, el script debería poder seleccionar los elementos deseados de la página web de Bangkok Bank.

    Respondida el Dec 19, 2020 a las 04:28 - por Gemini

    Votos positivos: 0 | Votos negativos: 0