
Акции (акции) – один из самых популярных финансовых инструментов. Выпуск акций является одним из вариантов финансирования компании. Более того, акции — самый любимый инвестиционный инструмент инвесторов, поскольку они предлагают им интересную доходность. — Индонезийская фондовая биржа
Как и любой другой продукт, цена акций зависит от спроса и предложения. Цены растут, когда предложения акций для покупки недостаточно для удовлетворения спроса инвесторов; они падают, когда меньше инвесторов заинтересованы в покупке акций. — Сантандер
В этой статье мы собираемся создать веб-скребок для сбора данных об акциях индонезийских публичных компаний. Этот веб-скребок определит самые высокие и самые низкие цены на акции за один год. Собранные данные об акциях будут записаны в файл JSON для удобства использования.
Отказ от ответственности. Этот проект предназначен только для учебных целей.
Инструменты
- Кукловод
Мы будем использовать сайт Yahoo Finance для получения исторических данных о цене акций.

Сначала создайте проект, создав папку, и используйте команду npm init внутри папки. Имя этого проекта — stocks-price-scraping.
Создайте option.js. option.js используется для определения наших акций и временного диапазона, который мы хотим отказаться. В этом проекте мы установили акции BBCA и UNVR, от January, 1 2010 до December, 31 2022 в формате временной метки.

Создайте scraper.js. Мы поместим сюда наш парсинг-код.
Поскольку на сайте Yahoo Finance есть отложенная загрузка, нам нужно прокрутить сайт вниз, чтобы могли появиться те данные, которые еще не появились. Итак, мы создаем функцию с именем scrollDown и вызываем ее.

У нас есть функция getStocksPrice, с помощью этой функции мы запускаем браузер и переходим на сайт Yahoo Finance. В URL-адресе есть 3 переменные: stocks, startTimestamp и endTimestamp.

В Yahoo Finance данные отображаются в табличной форме, поэтому мы можем использовать $$eval, чтобы получить все строки таблицы и сопоставить их с каждой строкой. Нам нужен первый столбец для даты, чтобы преобразовать ее в год, третий столбец, чтобы получить самое высокое значение, и четвертый столбец, чтобы получить самое низкое значение для каждого месяца.

По некоторым акциям они выплачивают дивиденды акционерам, и это также зафиксировано в данных Yahoo Finance. Но нам не нужны эти данные, поэтому мы просто проверяем, существуют ли третий и четвертый столбцы. Если они существуют, мы возвращаем данные, а если они не существуют, они возвращают null.
Поскольку в stocksMonthlyData есть null, мы отфильтруем его, чтобы удалить данные null, чтобы данные больше не содержали значения null.

Затем мы просматриваем данные non-null и сравниваем самые высокие и самые низкие данные за каждый месяц в течение одного года.

После завершения цикла мы помещаем объект данных о запасах в массив с именем stocksPrice. Затем закройте браузер и верните stocksPrice.

Экспортируйте функцию getStocksPrice в переменную с именем allStocksData.

Полный код scraper.js
import puppeteer from "puppeteer";
import { stocks, startTimestamp, endTimestamp } from "./option.js";
//Scroll page to bottom
async function scrollDown(page) {
await page.evaluate(async () => {
scrollTo(0, 9999);
});
}
//Get stocks price
const getStocksPrice = async () => {
let stocksPrice = [];
//Launch browser
const browser = await puppeteer.launch({
headless: 'new',
defaultViewport: false,
});
//Create new page
const page = await browser.newPage();
for (let i = 0; i < stocks.length; i++) {
await page.goto(`https://finance.yahoo.com/quote/${stocks[i]}.JK/history?period1=${startTimestamp}&period2=${endTimestamp}&interval=1mo`, {timeout: 0, waitUntil: "networkidle2"});
await scrollDown(page);
//Get stocks price data each month
const stocksMonthlyData = await page.$$eval('table > tbody > tr', (el) => {
return el.map((el) => {
if ((el.querySelector('td:nth-child(3)') !== null) && el.querySelector('td:nth-child(4)') !== null) {
let date = el.querySelector('td:nth-child(1) > span').textContent;
let newDate = new Date(date);
const year = newDate.getFullYear();
return {
"date" : year,
"highest" : el.querySelector('td:nth-child(3) > span').textContent,
"lowest" : el.querySelector('td:nth-child(4) > span').textContent,
}
}
});
});
//Remove null element in array
const result = stocksMonthlyData.filter((element) => element!=null);
let highest = 0;
let lowest = 0;
let year_data = "";
let stocksData = [];
//Compare highest and lowest stocks data in a year
result.forEach((data) => {
data.highest = data.highest.replace(/,/g, '');
data.lowest = data.lowest.replace(/,/g, '');
if (year_data != data.date) {
if (year_data != "") {
stocksData.push({
"year": year_data,
"highest": highest,
"lowest": lowest,
});
}
highest = parseInt(data.highest);
lowest = parseInt(data.lowest);
} else {
if (highest < parseInt(data.highest)) {
highest = parseInt(data.highest);
}
if (lowest==0 || lowest > parseInt(data.lowest)) {
lowest = parseInt(data.lowest);
}
}
year_data = data.date;
});
stocksData.push({
"year": year_data,
"highest": highest,
"lowest": lowest,
});
stocksPrice = [...stocksPrice, {"name": stocks[i], "data" : stocksData}];
}
//Close browser
await browser.close();
return stocksPrice;
}
export let allStocksData = await getStocksPrice();
Создайте index.js внутри каталога проекта, в index.js мы вызовем код очистки из scraper.js и запишем его в файл JSON с именем stocks_price.json.

И поместите в package.json стартовые сценарии, которые будут запускать node index.

Запустите npm run start и в результате будет записан stocks_price.json файл.
[
{
"name": "BBCA",
"data": [
{
"year": 2022,
"highest": 9400,
"lowest": 7000
},
{
"year": 2021,
"highest": 8250,
"lowest": 5905
},
{
"year": 2020,
"highest": 7060,
"lowest": 4325
},
{
"year": 2019,
"highest": 6800,
"lowest": 5115
},
{
"year": 2018,
"highest": 5395,
"lowest": 4120
},
{
"year": 2017,
"highest": 4550,
"lowest": 2990
},
{
"year": 2016,
"highest": 3240,
"lowest": 2525
},
{
"year": 2015,
"highest": 3120,
"lowest": 2200
},
{
"year": 2014,
"highest": 2715,
"lowest": 1850
},
{
"year": 2013,
"highest": 2500,
"lowest": 1690
},
{
"year": 2012,
"highest": 1900,
"lowest": 1350
},
{
"year": 2011,
"highest": 1770,
"lowest": 1060
},
{
"year": 2010,
"highest": 1440,
"lowest": 885
}
]
},
{
"name": "UNVR",
"data": [
{
"year": 2022,
"highest": 5475,
"lowest": 3280
},
{
"year": 2021,
"highest": 8000,
"lowest": 3800
},
{
"year": 2020,
"highest": 8800,
"lowest": 5275
},
{
"year": 2019,
"highest": 10105,
"lowest": 8070
},
{
"year": 2018,
"highest": 11620,
"lowest": 7780
},
{
"year": 2017,
"highest": 11195,
"lowest": 7760
},
{
"year": 2016,
"highest": 9560,
"lowest": 7060
},
{
"year": 2015,
"highest": 9200,
"lowest": 6420
},
{
"year": 2014,
"highest": 6600,
"lowest": 5160
},
{
"year": 2013,
"highest": 7470,
"lowest": 4180
},
{
"year": 2012,
"highest": 5700,
"lowest": 3500
},
{
"year": 2011,
"highest": 3800,
"lowest": 2760
},
{
"year": 2010,
"highest": 3840,
"lowest": 2110
}
]
}
]
Вот и все. Мы успешно создали наш парсер для отслеживания акций, позволяющий отслеживать самые высокие и самые низкие данные по запасам за один год. Надеюсь, вам, ребята, она понравится и вы найдете эту статью полезной. Спасибо, что прочитали мою статью. Увидимся в другой статье.
Код для очистки цен на акции можно найти в моем репозитории на GitHub. https://github.com/raptorz12/stocks-price-scraping
Не стесняйтесь обращаться ко мне.
Github: raptorz12
Linkedin: Джефри Антониус Карлия
Twitter: jefry_antonius