Как насчет законности скрапинга Yahoo Finance? Будет ли это считаться незаконной деятельностью?
Не волнуйтесь. Большая часть данных на сайте Yahoo Finance является открытой и общедоступной. Данные Yahoo Finance, которые мы можем скрапить, включают:
Хотя это верно в принципе, все же следует обращать внимание на местные законы и правила веб-скрапинга на всякий случай.
Прежде чем приступать к скрапингу, важно определить причины. Зачем нам это делать? Вот наш анализ.
Скрапинг актуальных данных позволяет инвесторам получить последние цены акций, объемы торгов и динамику рынка, чтобы принимать своевременные решения. Кроме того, анализируя исторические данные, инвесторы могут строить базовые модели для прогнозирования тенденций цен акций и помощи в формировании инвестиционной стратегии.
Мы всегда боимся рисков. Получение данных о доходности разных акций помогает оптимизировать наш инвестиционный портфель, чтобы снизить риски.
Финансовые отчеты, новости и другие события оказывают значительное влияние на цены акций. Скрапинг данных позволяет нам четко понимать фондовый рынок и помогать инвесторам принимать правильные решения.
После цикла инвестирования необходимо подвести итоги обратной связи по развитию вложенных средств. Использование Browserless для скрапинга данных позволяет своевременно и эффективно тестировать исторические данные и проверять эффективность торговых стратегий, тем самым повышая успешность сделок.
Однако Yahoo Finance может использовать такие меры, как блокировка IP, CAPTCHA и ограничение скорости запросов, чтобы предотвратить автоматический скрапинг. А поскольку некоторые данные могут загружаться динамически с помощью JavaScript, нам нужно использовать более мощную и стабильную программу для работы с динамическими веб-страницами.
Не расстраивайтесь! Browserless отлично справляется с этими проблемами.
Browserless — это облачное решение, разработанное для масштабируемой автоматизации браузера, веб-скрапинга и веб-тестирования. Browserless обладает встроенной совместимостью с Playwright и Puppeteer. Он также разработан с автоматическим решением CAPTCHA и прокси-сервисами. Кроме того, он оснащен расширяемой платформой с API для интеграции представлений в реальном времени и получения журналов и записей.
Browserless можно попробовать прямо сейчас!
Есть ли у вас замечательные идеи или сомнения по поводу веб-скрапинга и Browserless?
Давайте посмотрим, что другие разработчики делятся в Discord!
Для скрапинга Yahoo Finance нам понадобится сервис Browserless. Browserless от Nstbrowser — эффективный инструмент для решения сложных задач веб-скрапинга и масштабной автоматизации, поддерживающий полнофункциональное облачное развертывание.
Browserless использует браузерно-центрированный подход, обеспечивает мощные возможности бессерверного развертывания и обеспечивает более высокую производительность и надежность. Дополнительную информацию о Browserless можно найти в наших документах Browserless.
puppeteer-core
:# pnpm
pnpm i puppeteer-core
# yarn
yarn add puppeteer-core
# npm
npm i --save puppeteer-core
apiKey
и proxy
, чтобы начать последующие операции с 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()}`;
Прежде чем приступить к веб-скрапингу Yahoo Finance, сначала посмотрим на URL Yahoo Finance: https://finance.yahoo.com/quote/AAPL/. В нем AAPL
— это код акции.
Очевидно, что вы можете переключиться на необходимую страницу акций для сканирования, изменив путь с кодом акции. Затем откройте средство разработки (F12), чтобы проверить HTML-структуру страницы, и установите курсор на текущую рыночную цену.
Далее мы попробуем сканировать эту цену:
В ходе вышеописанной подготовки мы получили порт подключения Browserless, поэтому можем сразу же начать сканирование.
// connect to browserless
const browser = await puppeteer.connect({
browserWSEndpoint: browserlessWSEndpoint,
defaultViewport: null,
})
const page = await browser.newPage();
await page.goto('https://finance.yahoo.com/quote/AAPL');
// Add screenshots to facilitate subsequent troubleshooting
await page.screenshot({ path: 'yahoo.png' });
const selector = '[data-symbol="AAPL"][data-field="regularMarketPrice"]';
// Extract the inner text of an element matching a selector (i.e. a stock price)
const regularMarketPrice = await page.$eval(selector, el => el.innerText);
console.log(`Apple The current stock price is:${regularMarketPrice}`);
Подождите! Если мы запустим этот скрипт сейчас, он скорее всего не сработает. Почему? Давайте посмотрим на скриншот finance.png
, созданный при запуске скрипта.
Видно, что сканирование не удалось, потому что мы еще не выполнили авторизацию Cookie. Затем мы воспользуемся Puppeteer, чтобы пропустить авторизацию Cookie:
Принять все
таким же образом и получить соответствующий селектор классаВсе эти операции можно легко выполнить всего за несколько простых строк кода!
Следующий код используется, чтобы ждать появления на странице элемента с классом .consent-overlay
, а затем щелкнуть кнопку «Принять все» (.accept-all
) в слое. И нам нужно использовать try catch
, чтобы исключить ситуацию, когда Cookie уже авторизован.
try {
await page.waitForSelector('.consent-overlay');
// click the "accept all" button
await page.click('.consent-overlay .accept-all');
} catch (e) {
console.log('Cookie has been authorized');
}
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');
// click the "accept all" button
await page.click('.consent-overlay .accept-all');
} catch (e) {
console.log('Cookie has been authorized');
}
const selector = '[data-symbol="AAPL"][data-field="regularMarketPrice"]';
const regularMarketPrice = await page.$eval(selector, el => el.innerText);
console.log(`Apple The current stock price is:${regularMarketPrice}`);
Однако непосредственное указание кода акции в коде недостаточно гибко. Поэтому лучше добавить следующий код в начало скрипта. Этот код заставит скрипт выполняться с параметром скрипта: код акции.
const tickerSymbols = process.argv.slice(2);
if (tickerSymbols.length === 0) {
console.error('Ticker symbol CLI arguments missing!');
process.exit(2);
}
Поскольку кодов акций может быть несколько, необходимо определить массив (stockList
), чтобы получить сканированные результаты. В следующем коде мы будем использовать простой цикл для перебора и обработки входящего списка кодов акций.
// An array containing all the crawled data
const stockList = [];
for (const tickerSymbol of tickerSymbols) {
console.log(`Scraping data for: ${tickerSymbol}`);
// Navigate to Yahoo Finance page
await page.goto(`https://finance.yahoo.com/quote/${tickerSymbol}`);
try {
await page.waitForSelector('.consent-overlay');
// Click the "accept all" button
await page.click('.consent-overlay .accept-all');
} catch (e) { }
// Defining selectors using template literals and stock symbols
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"]`
};
// Initialize an empty object to store financial data
const financialData = { tickerSymbol };
// Loop through each selector to extract the text content
for (const [key, selector] of Object.entries(selectors)) {
try {
financialData[key] = await page.$eval(selector, el => el.innerText);
// Remove brackets for percentage values
if (key.includes('ChangePercent')) {
financialData[key] = financialData[key].replace('(', '').replace(')', '');
}
} catch {
financialData[key] = 'N/A'; // If the element is not found, the value is set to N/A
}
}
// Add the financial data of the current stock symbol to the stock array
stockList.push(financialData);
}
console.log(JSON.stringify(stockList, null, 2));
Запустите следующий скрипт:
node yahoo.mjs AAPL TSLA
Если все прошло успешно, на консоли будет напечатано следующее:
Очевидно, что для более глубокого анализа данных недостаточно просто выводить данные на консоль. Вот простой пример. Просто вручную добавьте следующий CSV-код, а затем используйте модуль fs для создания CSV-файла с результатами сканирования:
// Generate csv string and write to csv file
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('Ticker symbol CLI arguments missing!');
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('Connected!');
const page = await browser.newPage();
// An array containing all the crawled data
const stockList = [];
for (const tickerSymbol of tickerSymbols) {
console.log(`Scraping data for: ${tickerSymbol}`);
// Navigate to Yahoo Finance page
await page.goto(`https://finance.yahoo.com/quote/${tickerSymbol}`);
try {
await page.waitForSelector('.consent-overlay');
// Click the "accept all" button
await page.click('.consent-overlay .accept-all');
} catch (e) { }
// Defining selectors using template literals and stock symbols
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"]`
};
// Initialize an empty object to store financial data
const financialData = { tickerSymbol };
// Loop through each selector to extract the text content
for (const [key, selector] of Object.entries(selectors)) {
try {
financialData[key] = await page.$eval(selector, el => el.innerText);
// Remove brackets for percentage values
if (key.includes('ChangePercent')) {
financialData[key] = financialData[key].replace('(', '').replace(')', '');
}
} catch {
financialData[key] = 'N/A'; // If the element is not found, the value is set to N/A
}
}
// Add the financial data of the current stock symbol to the stock array
stockList.push(financialData);
}
console.log(JSON.stringify(stockList, null, 2));
// Generate csv string and write to csv file
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();
Теперь, после запуска скрипта, вы увидите не только вывод на консоль, но и созданный в текущей папке файл stocks_data.csv
.
В меню Browserless клиента Nstbrowser вы можете просмотреть статистику по недавним запросам и оставшемуся времени сеанса.
Browserless от Nstbrowser — это мощный инструмент веб-скрапинга и автоматизации. Он позволяет легко обходить обнаружение и обеспечивает стабильность при сканировании цен акций. В этом учебном пособии вы узнали:
Yahoo Finance — это типичный динамический сайт с продвинутой технологией защиты данных, встроенной на основе мощных функций JavaScript.
Поэтому, если вы хотите легко сканировать данные Yahoo Finance, вам нужен такой же мощный инструмент для сканирования. Наш бесплатный Browserless предоставляет вам самый удобный и быстрый способ сканирования. Достаточно всего нескольких строк кода, и все готово.
Начните использовать его бесплатно прямо сейчас!
Отказ от ответственности: Все данные и сайты, упомянутые в этой статье, используются только в демонстрационных целях. Мы решительно против незаконных и нарушающих права действий. Если у вас есть какие-либо вопросы или проблемы, пожалуйста, свяжитесь с нами незамедлительно.