Блог им. tomas_b88

Парсинг текущего значения цены акций Python.

 
Захотелось реализовать несколько идей для быстрого расчета по позициям акций и  для этого мне нужно было чтобы скрипт на python постоянно получал обновленное значение цены. Например раз в три секунды. Искал решение и нашел похожий пример с парсингом любой информации в интернете на python с применением блиотек requests и beautiful soup, (bs4)


На примере тикера GAZP продемонстрирую как можно спарсить текущий курс (например с гугла.)

 Кому лень читать всё что я тут написал можно скопипастить полный код в конце статьи :)


Парсинг текущего значения цены акций Python.



Для начала нужно установить нужные библиотеки, в консоли пишем : 
 

pip install requests bs4
 

Теперь перейдем к коду. 

Импортируем то, что установилось. Также нам понадобится библиотека time для задержки запросов по времени.

import requests  # для URL запроса
from bs4 import BeautifulSoup  # для работы с HTML
import time  # для установки задержки в цикле программы

Можно сразу задержку вынести в отдельную переменную, для экспериментов. 

sleep = 3  # время задержки

Идем на сайт гугл финансы и копируем ссылку,
Ссылка помещается в переменную GAZP
(для удобства читаемости кода я переносил строку ссылки через "\".)

# ссылка на тикер (Я использовал сайт google finance)
    GAZP = "https://www.google.com/" \
           "finance/quote/" \
           "GAZP:MCX?sa=X&ved=2ahUKEwjK5-z-yJLyAhUhpIsKHXbMBh0Q_AUoAXoECAEQAw"

Для формирования URL запроса нам потребуются заголовки my user agent, чтобы запрос не был воспринят гуглом как БОТ- запрос.
Эту строчку можно получить набрав в гугле поисковый запрос my user agent и скопировать то что будет сверху

Парсинг текущего значения цены акций Python.

Сохраняем эту строку в переменную headers

# заголовки для URL запроса.(добавляется к ссылке при URL запросе)
    headers = {
        'user agent': "Mozilla/5.0 (Windows NT 10.0; WOW64) "
                      "AppleWebKit/537.36 (KHTML, like Gecko) "
                      "Chrome/91.0.4472.135 Safari/537.36"}

Теперь у нас есть всё для того чтобы сформировать запрос. Результат запроса помещается в переменную, которая будет содержать всю HTML разметку данной страницы.

# запрашиваем страницу по ссылке и помещаем в переменную html
    html = requests.get(GAZP, headers)

Воспользуемся библиотекой BeautifulSoup чтобы спарсить все тэги из html, который был получен строчкой выше. 

# парсим данные в переменную soup
    soup = BeautifulSoup(html.content, 'html.parser')

Воспользуемся фильтром и найдем все тэги с признаком, который нам нужен. Для того, чтобы понять, какие именно тэги нужно искать, в браузере можно воспользоваться инструментами разработчика, чтобы посмотреть html разметку нужного элемента. В нашем случае наводим курсор мыши на цену бумаги, кликаем правой кнопкой и выбираем исследовать элемент, посмотреть код элемента или что-то в этом роде. 

Парсинг текущего значения цены акций Python.


Мы видим что наш объект помещен в тэг div с признаком class=«YMlKec fxKbKc» вот по этому признаку и найдем интересующий нас фрагмент страницы. Результат поиска записываем в переменную convert

# находим интересующий нас тэг с текущей ценой акции
    # (В браузере используем просмотр кода элемента для того чтобы найти это значение)
    convert = soup.findAll('div', {'class': 'YMlKec fxKbKc'})

После того как мы получили нужную нам строчку берем её первый элемент (первый считается с индексом[0]) и записываем полученную строку в переменную price. Но нужно еще сделать пару преобразований. Если мы распечатаем значение price то напечатается строка вида ₽286.05

Для начала избавимся от символа рубля в начале строки срезом этой строки [1:]

И также нам нужно конвертировать эту строку в число в формате float, так как сейчас она является текстом. 

# считываем 1й элемент как текст.
    # Делаем срез и избавляемся от знака ₽ в начале строки,
    # конвертируем строку в число типа float
    price = float(convert[0].text[1:])

Теперь мы можем работать с полученным значением. price :) 
Для проверки выведем на печать

print("Цена акции Газпром: ", price)

Создадим функцию update_ticker(): и поместим туда весь код, который мы написали выше. В конце функции укажем задержку по времени. Воспользуемся функцией sleep библиотеки time и передадим ей одноименный аргумент sleep, который мы объявили вначале программы. 

Для того чтобы функция повторялась вызовем её повторно прямо из этой же функции .

# устанавливаем задержку
time.sleep(sleep)
update_ticker()  # вызываем эту же функцию снова

Можно сделать и по другому, но это не боевой вариант а прототип, демонстрирующий возможности парсера с повторением запроса по таймеру. 

Функция готова и чтобы всё заработало вызываем её один раз в начале программы. Далее она вызывает сама себя с интервалом в sleep, 3 секунды. 

Полный код этого примера : 
import requests  # для URL запроса
from bs4 import BeautifulSoup  # для работы с HTML
import time  # для установки задержки в цикле программы

sleep = 3  # время задержки


def update_ticker():
    # ссылка на тикер (Я использовал сайт google finance)
    GAZP = "https://www.google.com/" \
           "finance/quote/" \
           "GAZP:MCX?sa=X&ved=2ahUKEwjK5-z-yJLyAhUhpIsKHXbMBh0Q_AUoAXoECAEQAw"

    # заголовки для URL запроса.(добавляется к ссылке при URL запросе)
    headers = {
        'user agent': "Mozilla/5.0 (Windows NT 10.0; WOW64) "
                      "AppleWebKit/537.36 (KHTML, like Gecko) "
                      "Chrome/91.0.4472.135 Safari/537.36"}

    # запрашиваем страницу по ссылке и помещаем в переменную html
    html = requests.get(GAZP, headers)

    # парсим данные в переменную soup
    soup = BeautifulSoup(html.content, 'html.parser')

    # находим интересующий нас тэг с текущим курсом
    # (В браузере используем просмотр кода элемента для того чтобы найти это значение)
    convert = soup.findAll('div', {'class': 'YMlKec fxKbKc'})

    # считываем 1й элемент как текст.
    # Делаем срез и избавляемся от знака ₽ в начале строки,
    # конвертируем строку в число типа float
    price = float(convert[0].text[1:])

    print("Цена акции Газпром: ", price)
    # устанавливаем задержку
    time.sleep(sleep)
    update_ticker()  # вызываем эту же функцию снова


update_ticker()


 
6.5К | ★19
25 комментариев
две мои любимые библиотеки для работы BeautifulSoup и Selenium ))
avatar
Mantis, до сегодняшнего дня и не знал что это такое ) теперь мне тоже это нравится  буду парсить всё подряд 
avatar
шляпа по названию класса парсить. поменяют id и привет.
если уж хочется, то лучше разобрать xml с yahoo finance. 
avatar
DoubleBubble, а как еще можно 
avatar
tomas_b88, вот открой в браузере (https://query2.finance.yahoo.com/v7/finance/quote?symbols=CHMF.ME) и потом разбирай спокойно любым xml парсером. все параметры четкие и не меняются. плюс есть ещё и всякие другие плюшки в виде % изменения, PE, PB (но не везде)
avatar
DoubleBubble, попробую :)
avatar
Теперь у нас есть всё для того чтобы сформировать запрос. Результат запроса помещается в переменную, которая будет содержать всю HTML разметку данной страницы.
.....
Тупиковый вариант. HTML код страниц достаточно часто меняется, и потом хрен найдешь эту ссылку.
avatar
3Qu, ну да.  в принципе можно генерить новую просто поисковым запросом 
avatar
tomas_b88, это утопия. см. выше как надо :)
avatar
DoubleBubble, xml с yahoo finance? ) ок попробую переделать 
avatar
Я никогда не смотрел, но сдаётся мне, что у гугла точно есть API, для таких вещей. 

Вот первая ссылка.

support.google.com/docs/answer/3093281?hl=ru
avatar
Gravizapa, о, ниче себе. спасибо.  написано что 
MCX Московская биржа В режиме реального времени

попробую использовать :) 
avatar
tomas_b88, Прежде всего, найди какие ограничения для бесплатного использования. А то там может 10 запросов в день)
avatar
alor open api, REST-клиент для Python есть в примерах, websocket-клиента — чтобы уж совсем кошерный реалтайм — сделать недолго. 
avatar
tashik, Благодарю за наводку ) тоже рассмотрю поближе 
avatar
Я понял, чтобы собрать пул годных советов по решению задачи, нужно попробовать выложить на коленке собранный вариант 
avatar
Не проще текущую цену напрямую скачивать с московской бирже? Через запросы ISS Queries (moex.com)

 

avatar
Riskplayer, может и проще ) не пробовал, попробую обязательно все предложенные варианты :) 
avatar
Слишком сложная связка. Попробуй pandas, или pandas-finance. В pandas-finance реализован доступ к фондоврй секции moex. Фьючерсы там криво загружаются. Все примеры, как работать с библиотекой, есть в сети.
Что касается pandas, то через библиотеку можно выгружать csv данные по инструментам через moex api. Но там придется много обработок делать.
avatar
Артем, Спасибо! буду пробовать
avatar
tomas_b88, Есть еще библиотека apimoex. Тоже удобно.
avatar
Riskplayer, наткнулся на нее вчера тоже. пока на заметочку оставлю. Пригодится для дальнейших экспериментов. Сейчас я решил пока остановиться на варианте с json запроса с yahoo. Попробовал оч. удобно и под эту задачу норм подходит и заморочек минимум. получаем json вытаскиваем нужную строчку.
avatar
можно проще через power query запарсить инфо
Игнатов Виталий, можно но скрипт планируется делать автономным без GUI и запускать его на debian. помимо парсера там будут крутиться еще пара скриптов. На самом деле способов великое множество оказалось. я выбрал способ получения инфы с yahoo либо через библиотеку yfinance либо через свой класс. Остановился на своем т.к. он заточен только под то что нужно и я не нашел некоторых функций в yfinance. 
Тут сравнил два способа smart-lab.ru/blog/713434.php
avatar
попробовал покачто через json запрос на yahoo 
Написал пример ТУТ  
avatar

Читайте на SMART-LAB:
Фото
Газета «Коммерсант» выпустила тематическое приложение о страховом рынке
Много интересных материалов для тех, кто работает в отрасли и тех, кто так или иначе с ней связан. Полагаем, публикации могут быть интересны и...
Фото
🥳 В десяточку! Два выпуска на сумму более 10 млрд рублей
ГК «А101» завершила сбор книги заявок на два выпуска облигаций общим объемом 10,5 млрд рублей. Начало торгов состоится 26 декабря....
Выгодны ли кредит под залог криптовалюты
Зампредправления Сбера Анатолий Попов заявил, что со временем банк может предложить кредиты под залог криптовалют. Подробности о том, для какой...
Фото
Какая доходность среди облигаций с наивысшим рейтингом надежности и сроком погашения от 3 лет?

теги блога tomas_b88

....все тэги



UPDONW
Новый дизайн