WebSocket для получения автоматически обновляющихся криптографических данных

Один из лучших способов автоматизировать получение данных с сайта —  создать веб-сборщика, выполняющего эту работу. Вы можете запрограммировать его на сбор данных различными методами. Например, чтобы получать данные с сайта один раз в несколько часов или в неделю, нужно написать программу, которая будет автоматически отправлять HTTP-запрос или открывать браузер. Однако, если вам необходимо получать данные в течение нескольких секунд, все же лучше подключаться через веб-сокет (протокол дуплексной связи).

Прежде чем перейти к практической части программирования веб-сборщика, рассмотрим вкратце, что это такое и в каких случаях используется.

Проведем аналогию с ситуацией из повседневной жизни. Вы сказали другу, что позвоните ему, чтобы обсудить непонятную вам концепцию. Когда вы звоните ему (подтверждение соединения), он сначала проверяет, кто звонит, а затем решает, принимать ли звонок (верификация). Завершив проверку и приняв звонок, друг начнет объяснять концепцию и держать линию открытой для ваших входящих запросов (поток данных с сервера).

Блок-схема, объясняющая алгоритм действия веб-сокета

Обычно WebSocket используют для получения данных:

  • о курсах криптовалют;
  • о текущих ценах на акции;
  • о ставках в реальном времени;
  • об обмене сообщениями в live-режиме;
  • о торговой платформе.

Теперь перейдем от теории к практике. Представьте, что вам нужно создать live-бота для торговли криптовалютами и вы уже разработали набор стратегий, чтобы обойти рынок. Что дальше?

Понадобится сайт, с которого можно получать данные в реальном времени. Вы перебираете разные варианты API, но опасаетесь, что они могут выйти из строя и вы потеряете деньги. Итак, вы решаете найти сайт, который предоставляет реальные цены на криптовалюты.

Допустим, ваш выбор падает на Cryptocompare  —  поставщика данных о мировом криптовалютном рынке.

Исследование

Зайдя на этот сайт через Chrome, выполните следующие действия.

  • Щелкните правой кнопкой мыши и выберите пункт inspect.
  • Перейдите во вкладку WS  —  вам откроется изображение, похожее на скриншот выше (вы увидите, что url запроса для этого веб-сокета wss://streamer.cryptocompare.com/v2?format=streamer).
  • Перейдите во вкладку Message, чтобы получить сообщение, которое необходимо отправить на сервер для завершения верификации.

Обратите внимание на два типа стрелок.

  1. Зеленые указывают на исходящие сообщения, которые браузер отправляет на сервер.
  2. Красные обозначают входящие данные, получаемые браузером от сервера.

На данном этапе нужно просто скопировать 5 сообщений, отмеченных зеленой стрелкой. Для этого щелкните правой кнопкой мыши по каждому сообщению и выберите copy message. Эти сообщения понадобятся при написании кода.


Написание кода

from websocket import create_connection
import json

# Скопируйте заголовок браузера и вставьте его в виде словаря
headers = json.dumps({
'Pragma': 'no-cache',
'Origin': 'https://www.cryptocompare.com',
'Accept-Language': 'en-US,en;q=0.9',
'Sec-WebSocket-Key': 'QknTzkhVwUs8UY+xAE22Kg==',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36',
'Upgrade': 'websocket',
'Sec-WebSocket-Extensions': 'permessage-deflate; client_max_window_bits',
'Cache-Control': 'no-cache',
'Connection': 'Upgrade',
'Sec-WebSocket-Version': '13',
})

# Запустите соединения с сервером (выполнение рукопожатия)
ws = create_connection('wss://streamer.cryptocompare.com/v2?format=streamer',headers=headers)

# Отправка исходящих сообщений на сервер
ws.send(json.dumps({"action":"SubAdd","subs":["24~CCCAGG~BTC~USD~H"]}))
ws.send(json.dumps({"action":"SubAdd","subs":["24~CCCAGG~ETH~USD~H"]}))
ws.send(json.dumps({"action":"SubAdd","subs":["5~CCCAGG~LTC~USD","24~CCCAGG~LTC~USD~H"]}))
ws.send(json.dumps({"action":"SubAdd","subs":["24~CCCAGG~XRP~USD~H"]}))
ws.send(json.dumps({"action":"SubAdd","subs":["11~BTC","21~BTC","5~CCCAGG~BTC~USD","11~ETH","21~ETH","5~CCCAGG~ETH~USD","11~SHIB","21~SHIB","5~CCCAGG~SHIB~USD","11~SOL","21~SOL","5~CCCAGG~SOL~USD","11~OMG","21~OMG","5~CCCAGG~OMG~USD","11~XRP","21~XRP","5~CCCAGG~XRP~USD","11~DOT","21~DOT","5~CCCAGG~DOT~USD","11~BUSD","21~BUSD","5~CCCAGG~BUSD~USD","11~ADA","21~ADA","5~CCCAGG~ADA~USD","11~SAND","21~SAND","5~CCCAGG~SAND~USD"]}))

# Получение входящих сообщений
while True:
try:
result = ws.recv()
print(result)
except Exception as e:
print(e)
break

Выше представлен фрагмент кода для примера. Обратите внимание на то, что необходимо изменить ключ WebSocket (Sec-WebSocket-Key) на тот, который вы получите из браузера во вкладке Headers. Пример ниже:

Поиск ключа Sec-WebSocket-Key

Вот краткое описание того, что выполняет приведенный выше фрагмент кода.

  1. Создает соединения с url запроса.
  2. Отправляет 5 исходящих сообщений на сервер.

Теперь ждите входящих сообщений (обычно это происходит в течение нескольких секунд).


Результат

Сохраните фрагмент кода в файл python и запустите его. Вы должны увидеть результат, аналогичный приведенному выше.


Возможные проблемы

Вот некоторые проблемы, с которыми можно столкнуться, и способы их решения.

1. Сообщение об ошибке: Connection is already closed

Это сообщение обычно означает, что сервер мешает вам подключиться. Самый быстрый способ решить эту проблему  —  сменить прокси-сервер или использовать VPN.

2. Код состояния HTTP: 401 (Unauthorized)

Ответ 401 означает, что сервер не принимает запрос на подключение. Если сервер работает нормально, значит, проблема в самом запросе. Возможно, вы используете неправильные учетные данные. Чтобы решить эту проблему, проверьте заголовки запроса и измените их соответствующим образом.

3. Код состояния HTTP: 403 (Forbidden)

Аналогично 401, но в данном случае повторная аутентификация ничего не изменит. Это может означать, что первоначальная логика приложения изменилась, например изменился процесс подтверждения соединения. Чтобы убедиться в отлаженной работе приложения, проверьте заголовки запросов и сообщения, которые необходимо отправить на сервер.

Читайте также:

Читайте нас в TelegramVK и Яндекс.Дзен


Перевод статьи Low Wei Hong: Why you should use WebSocket to retrieve live crypto data

Предыдущая статьяТоп-10 книг для Java-программистов
Следующая статья3 функции Python Matplotlib: повысьте информативность визуализации данных