Акции (акции) – один из самых популярных финансовых инструментов. Выпуск акций является одним из вариантов финансирования компании. Более того, акции — самый любимый инвестиционный инструмент инвесторов, поскольку они предлагают им интересную доходность. — Индонезийская фондовая биржа

Как и любой другой продукт, цена акций зависит от спроса и предложения. Цены растут, когда предложения акций для покупки недостаточно для удовлетворения спроса инвесторов; они падают, когда меньше инвесторов заинтересованы в покупке акций. — Сантандер

В этой статье мы собираемся создать веб-скребок для сбора данных об акциях индонезийских публичных компаний. Этот веб-скребок определит самые высокие и самые низкие цены на акции за один год. Собранные данные об акциях будут записаны в файл 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