CoderCastrov logo
CoderCastrov
Робинхуд Приложение

Извлечение истории транзакций в CSV из Robinhood с использованием Python (Парсинг)

Извлечение истории транзакций в CSV из Robinhood с использованием Python (Парсинг)
просмотров
7 мин чтение
#Робинхуд Приложение

Если вы знакомы с финансовыми рынками и акциями, то, вероятно, знаете, что недавно Robinhood (HOOD) провел IPO. Несколько дней назад я пытался найти функцию для загрузки моих прошлых транзакций. К сожалению, я не смог найти ничего, кроме ежемесячных отчетов или налоговых документов. Ничего в формате CSV! Это позор для такой крупной программной компании, которая не имеет такой простой функции.

Что мне делать теперь? Вводить их вручную в электронную таблицу? Конечно нет. У меня нет на это столько времени. Кроме того, я (или любой человек) подвержен ошибкам при ручном вводе чисел. К счастью, я знаю Python и умею парсить данные из Интернета. Так что мне нужно найти способ извлечь эти данные и поместить их в файл CSV. Давайте к этому приступим.


Предварительные требования, зависимости и процесс

Предварительные требования: Основы HTML, CSS и Javascript. XPath. Python.

Используемые библиотеки: Selenium, BeautifulSoup, python-dotenv

Процесс:

Шаги 1-4 выполняются с использованием Selenium, но на шаге 5 мы собираемся использовать BeautifulSoup. Вы можете выполнить шаги 1-4 вручную, так как это не займет много времени, и сразу перейти к шагу 5 для извлечения данных. Они являются двумя полностью отдельными частями.

Также вы можете посмотреть исходный код на GitHub: https://github.com/MRyderOC/robinhood-history-to-CSV


0. Зависимости

Ниже приведен код для импорта необходимых библиотек.

1. Вход в систему

В целях безопасности мы собираемся хранить наши имя пользователя и пароль в файле .env и загружать его в наш скрипт с помощью библиотеки python-dotenv.

Давайте определим функцию для выполнения шагов 1-4. Эта функция принимает USERNAME и PASSWORD, а затем записывает исходный код страницы истории на диск для дальнейшего использования. Также она принимает еще один аргумент path, чтобы указать место, где будет записан исходный код страницы.

Создадим WebDriver и загрузим страницу входа в Robinhood.

Мы используем geckodriver, который является WebDriver для Firefox. Довольно просто, не так ли?

Теперь пришло время ввести USERNAME и PASSWORD. Сначала нам нужно найти элементы текстового поля. В своем браузере Chrome перейдите в Просмотр → Разработчик → Инструменты разработчика или просто нажмите Command + Option + I (Shift + Ctrl + J).

Затем наведите указатель мыши на текстовое поле и щелкните, чтобы найти элемент. На правой странице вы можете увидеть элемент. Нам нужен XPath для него. Щелкните правой кнопкой мыши на элементе → Копировать → Копировать XPath.

Мы собираемся выполнить этот процесс несколько раз. Поэтому я буду называть его извлечением XPath.

Нам также нужно выполнить извлечение XPath для текстового поля пароля. Теперь, когда у нас есть XPath, мы можем найти элементы с помощью driver:

Теперь давайте заполним эти текстовые поля:

Функция .send_keys(sample_string) аналогична вводу sample_string в текстовое поле.

Единственное, что остается на этой странице, это нажать кнопку "Войти". Извлеките XPath для кнопки "Войти" и просто используйте функцию .click(), чтобы нажать на кнопку:

2. Прохождение 2FA

Вот и пришла сложная часть! Здесь могут произойти две ситуации. Либо вы уже включили 2FA, либо нет (по крайней мере, я видел эти две!). Если вы уже включили 2FA, сайт потребует ввести 6-значный код. Если вы не включали 2FA, будет показана кнопка для отправки SMS. После нажатия на кнопку SMS, снова потребуется ввести 6-значный код. Что нам нужно? XPath кнопки SMS, XPath текстового поля для ввода 6-значного кода и XPath кнопки "Продолжить" для подтверждения кода. Как получить код? Используя встроенную функцию [input()](https://docs.python.org/3.9/library/functions.html#input) . Помните, что вы должны ввести код в терминале, а не в браузере. Если вы введете код в браузере, программа не продолжится. Давайте запишем это:

Вуаля! Мы вошли в систему!!!

3. Перейдите на страницу истории

Нам нужно нажать на "Аккаунт" в правом верхнем углу, а затем нажать на "История". Для этого нам понадобится XPath этих двух элементов.

Готово!! Мы на странице истории.

4. Скачайте всю историю

Есть одна вещь. На этой странице не отображается вся история. Если прокрутить вниз, можно увидеть, что страница загружает больше данных. Поэтому нам нужно прокрутить страницу до самого низа, а затем скачать исходный код страницы. Как мы можем это сделать? С помощью JavaScript! Мы можем выполнить JavaScript с помощью нашего driver с помощью функции execute_script(). Одна из этих функций JavaScript возвращает высоту прокрутки страницы: document.body.scrollHeight. Другая функция может прокрутить страницу: window.scrollTo(0, document.body.scrollHeight). Когда scrollHeight больше не меняется, мы достигаем нижней части страницы. Также нам нужно установить таймер ожидания, чтобы убедиться, что новые данные загружены.

Давайте воспользуемся ими:

Через несколько секунд (в зависимости от количества транзакций) вы достигнете нижней части и будете готовы скачать исходный код страницы и записать его на диск.

Помните наш аргумент path в find_history_page_by_selenium? Мы используем его здесь :). Теперь пришло время извлечь нужные нам данные с помощью BeautifulSoup.

5. Извлечение нужной информации

Если вы выполнили шаги 1-4, у вас теперь есть файл с именем path в текущем каталоге. Если нет, вам придется сделать это вручную (Войти → Аккаунт → История → Прокрутить вниз до конца → Инспектировать страницу → Редактировать как HTML → Скопировать в файл → Сохранить как name.html).


Мы используем BeautifulSoup для извлечения данных.

  • Почему BeautifulSoup? Потому что он прост в использовании.
  • Почему не Scrapy? Потому что это всего лишь одна страница. Мы можем получить то, что нам нужно с помощью небольшой библиотеки, такой как BeautifulSoup. Нам не нужен полноценный фреймворк для этого.
  • Можем ли мы интегрировать Selenium с Scrapy, чтобы автоматизировать эту работу? Да. Посмотрите здесь.

Прежде всего нам нужна функция, чтобы сделать список "готовым для CSV". Я имею в виду удаление всех запятых (,) из всех элементов списка. Это поможет нам очень много в будущем. Вы увидите.

Теперь давайте определим функцию, которая принимает path в качестве аргумента и записывает информацию о транзакциях на диск в формате CSV.

Насколько я знаю, здесь есть 6 типов транзакций:

Поэтому нам нужно 6 списков для хранения этих данных. Давайте прочитаем данные с помощью встроенной библиотеки codecs и создадим объект BeautifulSoup.

Функция .find() для тега div с классом col-12 используется для извлечения части html-файла, в которой содержится история транзакций:

Кроме того, если вы щелкнете на любой из этих транзакций, будут показаны дополнительные детали в зависимости от типа транзакции (перевод, акции, проценты и т. д.), такие как дата, символ, сумма, статус и т. д. Итак, у нас есть некоторые кнопки (щелчок по транзакции) и некоторые div-элементы (расширенная часть при щелчке на транзакцию), которые я называю trxsButtons и trxsDivs соответственно.

Как найти их? С их атрибутами: trxsButtons: имя_тега: header, атрибут: class='rh-expandable-item-header-98210179'``trxsDivs: имя_тега: div, атрибут: class='css-2ae82m'

В каждой транзакции в trxsButtons есть дополнительный символ \n в их тексте. Поэтому мы должны избавиться от них также. (строка 3 вышеуказанного кода). Кроме того, в каждой транзакции в trxsDivs нам нужен только текст тегов span с классом css-ktio0g, и нам также нужно избавиться от запятых.

Кроме того, нам нужна некоторая структура данных, чтобы отслеживать посещенные транзакции, которые я называю divs_and_buttons, и мы будем хранить соответствующие buttons и divs каждой транзакции в этом словаре. (строка 10) Теперь мы можем избавиться от divs, buttons, trxsDivs, trxsButtons. (строка 11)

Остальное - это просто извлечение нужных данных с использованием этого словаря. Большинство из них просты и понятны, если вы выведете divs_and_buttons и посмотрите на структуру. За исключением дивидендов. Об этом я расскажу позже.

Акции, криптовалюты и корпоративные действия

Переводы, проценты и дивиденды

Проблема с дивидендами заключается в том, что они не включают имена тикеров, и некоторые даты отсутствуют. Кроме того, их текстовый формат несовместим с файлами CSV. Поэтому мы включим дивиденды в список и будем работать с ними в отдельной части.

Другие

Эта часть предназначена для транзакций, которые не подходят ни под одну из вышеперечисленных категорий, например, бонусы. Если divs_and_buttons['visited'] == 'False', то транзакция относится к этой категории.

Запись в файл

Теперь нам просто нужно записать списки в отдельные файлы:

Заключение

Это процесс парсинга данных с веб-сайта Robinhood, и честно говоря, в реальном мире вам придется бороться с такими беспорядочными данными, если у вас нет API или чистого способа сбора данных.

Конечно, этот скрипт подвержен ошибкам. Фактически, каждый скрипт парсинга подвержен ошибкам. Почему? Потому что он зависит от архитектуры веб-сайта. Если разработчики изменят веб-сайт, ваш скрипт перестанет работать. В частности, в этом скрипте я захватываю части или транзакции, с которыми столкнулся в своей учетной записи, и возможно, что ваша учетная запись отличается. Пожалуйста, сообщите мне, если вы найдете в нем ошибки. Вы можете сделать это, открыв проблему здесь.

Рекомендую просмотреть транзакции после парсинга. Как я уже сказал, этот скрипт подвержен ошибкам.

Надеюсь, вам понравилось!!