¿Qué pasa con la legalidad de raspar Yahoo Finance? ¿Se reconocerá como una actividad ilegal?
No te preocupes. La mayoría de los datos en el sitio web de Yahoo Finance son de código abierto e información pública. Los datos de Yahoo Finance que podemos raspar incluyen:
Aunque esto es cierto en principio, aún debes prestar atención a las leyes y regulaciones locales de raspado web por si acaso.
Antes de raspar, es importante averiguar las razones. ¿Por qué deberíamos raspar? Aquí podemos darte el análisis.
Al raspar datos recientes, los inversores pueden obtener los últimos precios de las acciones, volúmenes de negociación y dinámica del mercado, para tomar decisiones oportunas. Además, al analizar datos históricos, los inversores pueden construir modelos básicos para predecir las tendencias de los precios de las acciones y ayudar en la formulación de estrategias de inversión.
Siempre tenemos miedo a los riesgos. Podemos obtener datos de rendimiento de diferentes acciones para ayudarnos a optimizar nuestra cartera de inversión y reducir los riesgos.
Los informes financieros, las noticias y otros eventos tienen un impacto significativo en los precios de las acciones. Al raspar datos, podemos comprender claramente el mercado de valores y ayudar a los inversores a tomar decisiones correctas.
Después de un ciclo de inversión, necesitamos dar un resumen de la retroalimentación sobre el desarrollo de los fondos invertidos. Usar Browserless para raspar datos puede probar de manera oportuna y efectiva los datos históricos y verificar la efectividad de las estrategias comerciales, mejorando así la tasa de éxito de las transacciones.
Sin embargo, Yahoo Finance puede usar medidas como bloqueo de IP, CAPTCHAs y limitación de la tasa de solicitud para evitar el raspado automatizado. Y debido a que algunos datos pueden cargarse dinámicamente a través de JavaScript, necesitamos usar un programa más potente y estable para manejar páginas web dinámicas.
¡No te preocupes! Browserless juega bien para lidiar con estos problemas.
Browserless es una solución basada en la nube diseñada para automatización de navegador escalable, raspado web y pruebas web. Browserless tiene compatibilidad nativa con Playwright y Puppeteer. También está diseñado con resolución automática de captcha y servicios proxy. Además, equipa una plataforma extensible con API para integrar vistas en tiempo real y recuperar registros y grabaciones.
Browserless ya está totalmente listo para probar!
¿Tienes alguna idea maravillosa o dudas sobre el raspado web y Browserless?
¡Veamos qué comparten otros desarrolladores en Discord!
El servicio Browserless es necesario para que podamos raspar Yahoo Finance. Browserless de Nstbrowser es una herramienta eficaz para manejar tareas complejas de raspado web y automatización a gran escala, y admite la implementación en la nube totalmente administrada.
Browserless adopta un enfoque centrado en el navegador, proporciona potentes capacidades de implementación sin cabeza y ofrece un mayor rendimiento y confiabilidad. Para obtener más información sobre Browserless, puedes aprender de nuestros documentos de Browserless.

puppeteer-core más ligero:# pnpm
pnpm i puppeteer-core
# yarn
yarn add puppeteer-core
# npm
npm i --save puppeteer-core
apiKey y el proxy para iniciar las operaciones subsiguientes de Browserless:import puppeteer from "puppeteer-core";
const apiKey = "your ApiKey"; // required
const config = {
proxy: 'your proxy', // required; input format: schema://user:password@host:port eg: http://user:password@localhost:8080
// platform: 'windows', // support: windows, mac, linux
// kernel: 'chromium', // only support: chromium
// kernelMilestone: '128', // support: 128
// args: {
// "--proxy-bypass-list": "detect.nstbrowser.io"
// }, // browser args
// fingerprint: {
// userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.85 Safari/537.36', // userAgent supportted since v0.15.0
// },
};
const query = new URLSearchParams({
token: apiKey, // required
config: JSON.stringify(config),
});
const browserlessWSEndpoint = `https://less.nstbrowser.io/connect?${query.toString()}`;
Antes de comenzar a raspar datos de Yahoo Finance, podemos observar primero la URL de Yahoo Finance: https://finance.yahoo.com/quote/AAPL/. Entre ellos, AAPL es el código de la acción.
Obviamente, puedes cambiar a la página de acciones que necesitas rastrear cambiando la ruta del código de la acción. Luego, abre la herramienta de desarrollo (F12) para verificar la estructura HTML de la página y coloca el cursor en el precio de mercado actual.
A continuación, intentaremos rastrear este precio:

En los preparativos anteriores, hemos obtenido el puerto de conexión de Browserless, por lo que podemos comenzar a rastrear directamente.
// conecta a browserless
const browser = await puppeteer.connect({
browserWSEndpoint: browserlessWSEndpoint,
defaultViewport: null,
})
const page = await browser.newPage();
await page.goto('https://finance.yahoo.com/quote/AAPL');
// Agrega capturas de pantalla para facilitar la solución de problemas posteriores
await page.screenshot({ path: 'yahoo.png' });
const selector = '[data-symbol="AAPL"][data-field="regularMarketPrice"]';
// Extrae el texto interno de un elemento que coincida con un selector (es decir, un precio de acción)
const regularMarketPrice = await page.$eval(selector, el => el.innerText);
console.log(`Apple El precio actual de las acciones es:${regularMarketPrice}`);
¡Espera! Si ejecutamos el script anterior ahora, es muy probable que falle. ¿Por qué? Echemos un vistazo a la captura de pantalla finance.png generada cuando ejecuto el script.

Se puede ver que el error de rastreo es causado por nuestra falta de autorización de cookies. Luego, usaremos Puppeteer para ayudarnos a omitir la autorización de cookies:
Aceptar todo de la misma manera y obtener su selector de clase correspondiente
¡Las operaciones anteriores se pueden completar fácilmente con solo unas pocas líneas de código simples!
El siguiente código se utiliza para esperar a que el elemento con la clase .consent-overlay aparezca en la página y luego hacer clic en el botón "Aceptar todo" (.accept-all) en la capa. Y necesitamos usar try catch para excluir la situación en la que la cookie ya ha sido autorizada.
try {
await page.waitForSelector('.consent-overlay');
// haz clic en el botón "Aceptar todo"
await page.click('.consent-overlay .accept-all');
} catch (e) {
console.log('La cookie ha sido autorizada');
}
import puppeteer from "puppeteer-core";
const apiKey = "your ApiKey"; // 'your proxy'
const config = {
proxy: 'your proxy', // required; input format: schema://user:password@host:port eg: http://user:password@localhost:8080
// platform: 'windows', // support: windows, mac, linux
// kernel: 'chromium', // only support: chromium
// kernelMilestone: '128', // support: 128
// args: {
// "--proxy-bypass-list": "detect.nstbrowser.io"
// }, // browser args
// fingerprint: {
// userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.85 Safari/537.36', // userAgent supportted since v0.15.0
// },
};
const query = new URLSearchParams({
token: apiKey, // required
config: JSON.stringify(config),
});
const browserlessWSEndpoint = `https://less.nstbrowser.io/connect?${query.toString()}`;
const browser = await puppeteer.connect({
browserWSEndpoint: browserlessWSEndpoint,
defaultViewport: null,
})
const page = await browser.newPage();
await page.goto('https://finance.yahoo.com/quote/AAPL/');
await page.screenshot({ path: 'yahoo.png' });
try {
await page.waitForSelector('.consent-overlay');
// haz clic en el botón "Aceptar todo"
await page.click('.consent-overlay .accept-all');
} catch (e) {
console.log('La cookie ha sido autorizada');
}
const selector = '[data-symbol="AAPL"][data-field="regularMarketPrice"]';
const regularMarketPrice = await page.$eval(selector, el => el.innerText);
console.log(`Apple El precio actual de las acciones es:${regularMarketPrice}`);

Sin embargo, escribir el código de la acción directamente en el código no es lo suficientemente flexible. Entonces sería mejor agregar el siguiente código al principio del script. El siguiente código forzará la ejecución del script con el parámetro del script: código de la acción.
const tickerSymbols = process.argv.slice(2);
if (tickerSymbols.length === 0) {
console.error('¡Faltan argumentos CLI de símbolo de acción!');
process.exit(2);
}
Dado que puede haber múltiples códigos de acciones, necesitamos definir una matriz (stockList) para recibir los resultados rastreados. En el siguiente código, usaremos un bucle simple para recorrer y procesar la lista de códigos de acciones entrantes.
// Una matriz que contiene todos los datos rastreados
const stockList = [];
for (const tickerSymbol of tickerSymbols) {
console.log(`Rastreando datos para: ${tickerSymbol}`);
// Navega a la página de Yahoo Finance
await page.goto(`https://finance.yahoo.com/quote/${tickerSymbol}`);
try {
await page.waitForSelector('.consent-overlay');
// Haz clic en el botón "Aceptar todo"
await page.click('.consent-overlay .accept-all');
} catch (e) { }
// Definir selectores usando literales de plantilla y símbolos de acción
const selectors = {
regularMarketPrice: `[data-symbol="${tickerSymbol}"][data-field="regularMarketPrice"]`,
regularMarketChange: `[data-symbol="${tickerSymbol}"][data-field="regularMarketChange"]`,
regularMarketChangePercent: `[data-symbol="${tickerSymbol}"][data-field="regularMarketChangePercent"]`,
preMarketPrice: `[data-symbol="${tickerSymbol}"][data-field="preMarketPrice"]`,
preMarketChange: `[data-symbol="${tickerSymbol}"][data-field="preMarketChange"]`,
preMarketChangePercent: `[data-symbol="${tickerSymbol}"][data-field="preMarketChangePercent"]`
};
// Inicializa un objeto vacío para almacenar datos financieros
const financialData = { tickerSymbol };
// Recorre cada selector para extraer el contenido del texto
for (const [key, selector] of Object.entries(selectors)) {
try {
financialData[key] = await page.$eval(selector, el => el.innerText);
// Eliminar corchetes para valores de porcentaje
if (key.includes('ChangePercent')) {
financialData[key] = financialData[key].replace('(', '').replace(')', '');
}
} catch {
financialData[key] = 'N/A'; // Si el elemento no se encuentra, el valor se establece en N/A
}
}
// Agrega los datos financieros del símbolo de acción actual a la matriz de acciones
stockList.push(financialData);
}
console.log(JSON.stringify(stockList, null, 2));
Ejecuta el siguiente script:
node yahoo.mjs AAPL TSLA
Si se ejecuta correctamente, se imprimirá lo siguiente en la consola:

Obviamente, para un mejor análisis de datos, no es suficiente solo imprimir los datos en la consola. Aquí tienes un ejemplo sencillo. Simplemente corta y pega el CSV a continuación, y luego usa el módulo fs para crear un archivo CSV de los resultados rastreados:
// Genera una cadena csv y escribe en un archivo csv
let csvData = 'Ticker Symbol,Regular Market Price,Regular Market Change,Regular Market Change Percent,Pre Market Price,Pre Market Change,Pre Market Change Percent\n';
stockList.forEach(stock => {
csvData += `${stock.tickerSymbol},${stock.regularMarketPrice},${stock.regularMarketChange},${stock.regularMarketChangePercent},${stock.preMarketPrice},${stock.preMarketChange},${stock.preMarketChangePercent}\n`;
});
fs.writeFileSync('stocks_data.csv', csvData);
import puppeteer from "puppeteer-core";
import fs from 'fs'
const tickerSymbols = process.argv.slice(2);
if (tickerSymbols.length === 0) {
console.error('¡Faltan argumentos CLI de símbolo de acción!');
process.exit(2);
}
const apiKey = "your ApiKey"; // 'your proxy'
const config = {
proxy: 'your proxy', // required; input format: schema://user:password@host:port eg: http://user:password@localhost:8080
// platform: 'windows', // support: windows, mac, linux
// kernel: 'chromium', // only support: chromium
// kernelMilestone: '128', // support: 128
// args: {
// "--proxy-bypass-list": "detect.nstbrowser.io"
// }, // browser args
// fingerprint: {
// userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.85 Safari/537.36', // userAgent supportted since v0.15.0
// },
};
const query = new URLSearchParams({
token: apiKey, // required
config: JSON.stringify(config),
});
const browserlessWSEndpoint = `https://less.nstbrowser.io/connect?${query.toString()}`;
const browser = await puppeteer.connect({
browserWSEndpoint: browserlessWSEndpoint,
defaultViewport: null,
})
console.info('¡Conectado!');
const page = await browser.newPage();
// Una matriz que contiene todos los datos rastreados
const stockList = [];
for (const tickerSymbol of tickerSymbols) {
console.log(`Rastreando datos para: ${tickerSymbol}`);
// Navega a la página de Yahoo Finance
await page.goto(`https://finance.yahoo.com/quote/${tickerSymbol}`);
try {
await page.waitForSelector('.consent-overlay');
// Haz clic en el botón "Aceptar todo"
await page.click('.consent-overlay .accept-all');
} catch (e) { }
// Definir selectores usando literales de plantilla y símbolos de acción
const selectors = {
regularMarketPrice: `[data-symbol="${tickerSymbol}"][data-field="regularMarketPrice"]`,
regularMarketChange: `[data-symbol="${tickerSymbol}"][data-field="regularMarketChange"]`,
regularMarketChangePercent: `[data-symbol="${tickerSymbol}"][data-field="regularMarketChangePercent"]`,
preMarketPrice: `[data-symbol="${tickerSymbol}"][data-field="preMarketPrice"]`,
preMarketChange: `[data-symbol="${tickerSymbol}"][data-field="preMarketChange"]`,
preMarketChangePercent: `[data-symbol="${tickerSymbol}"][data-field="preMarketChangePercent"]`
};
// Inicializa un objeto vacío para almacenar datos financieros
const financialData = { tickerSymbol };
// Recorre cada selector para extraer el contenido del texto
for (const [key, selector] of Object.entries(selectors)) {
try {
financialData[key] = await page.$eval(selector, el => el.innerText);
// Eliminar corchetes para valores de porcentaje
if (key.includes('ChangePercent')) {
financialData[key] = financialData[key].replace('(', '').replace(')', '');
}
} catch {
financialData[key] = 'N/A'; // Si el elemento no se encuentra, el valor se establece en N/A
}
}
// Agrega los datos financieros del símbolo de acción actual a la matriz de acciones
stockList.push(financialData);
}
console.log(JSON.stringify(stockList, null, 2));
// Genera una cadena csv y escribe en un archivo csv
let csvData = 'Ticker Symbol,Regular Market Price,Regular Market Change,Regular Market Change Percent,Pre Market Price,Pre Market Change,Pre Market Change Percent\n';
stockList.forEach(stock => {
csvData += `${stock.tickerSymbol},${stock.regularMarketPrice},${stock.regularMarketChange},${stock.regularMarketChangePercent},${stock.preMarketPrice},${stock.preMarketChange},${stock.preMarketChangePercent}\n`;
});
fs.writeFileSync('stocks_data.csv', csvData);
await browser.close();
Ahora, después de ejecutar el script, no solo puedes ver la impresión de la consola, sino que también puedes ver el archivo stocks_data.csv escrito en la ruta actual.

Puedes ver las estadísticas de las solicitudes recientes y el tiempo de sesión restante en el menú de Browserless del cliente Nstbrowser.

Browserless de Nstbrowser es una poderosa herramienta de raspado web y automatización. Puede omitir fácilmente la detección y garantizar la estabilidad al raspar los precios de las acciones. En este tutorial, aprendiste:
Yahoo Finance es un sitio web dinámico típico con tecnología avanzada de protección de datos incorporada basada en las potentes funciones de JavaScript.
Entonces, si quieres raspar datos de Yahoo Finance fácilmente, debes usar una herramienta de raspado igualmente potente. Nuestro Browserless gratuito te proporciona la forma más conveniente y rápida de raspar. Solo llama a unas pocas líneas de código y podrás hacerlo.
¡Comienza a usarlo gratis ahora!
Aviso legal: Cualquier dato y sitio web mencionado en este artículo tiene fines de demostración únicamente. Nos oponemos firmemente a las actividades ilegales e infractoras. Si tienes alguna pregunta o inquietud, contáctanos inmediatamente.