как извлекать данные из динамического графа в Python

Вопрос или проблема

Я пытаюсь получить данные из динамического линейного графика на этом сайте: https://www.xe.com/currencycharts/?from=SGD&to=USD&view=5Y.
Вы можете изменять временные интервалы на сайте, но все сетевые запросы выполняются при первой загрузке страницы и когда изменяется временной интервал, единственные сетевые запросы, которые выполняются, касаются данных под графиком.

Вкладка сети показывает, что одна из немногих ссылок, которую я нашел и которая получает несколько похожие данные: https://www.xe.com/api/protected/charting-rates/?fromCurrency=SGD&toCurrency=USD&crypto=true

Но когда я проверил сгенерированный Excel файл, данные, которые он показывает, никогда не были частью графика.

Вот скрипт

from datetime import datetime,timedelta
import requests
import pandas as pd
import os
BASE_DIR =os.getcwd()
url="https://www.xe.com/currencycharts/?from=SGD&to=USD&view=5Y"
data_url = "https://www.xe.com/api/protected/charting-rates/?fromCurrency=SGD&toCurrency=USD&crypto=true"

headers = {'authorization': 'Basic bG9kZXN0YXI6cHVnc25heA=='}
response = requests.get(data_url, headers=headers) 
if response.status_code == 200:
    try:
        # Парсинг содержимого JSON ответа
        response_data = response.json()
        timestamp = response_data.get('timestamp') / 1000

        # Преобразовать в удобочитаемую дату
        converted_date = datetime.fromtimestamp(timestamp)
        data_list = response_data.get('batchList')
        values_list = []
        for data_item in data_list:
            start_time = datetime.fromtimestamp(data_item.get('startTime')/1000)
            interval = timedelta(data_item.get('interval')/1000)
            for rate in data_item.get('rates'):
                values_list.append({'Timestamp' : converted_date,'Start Time': start_time, 'Interval' :interval , 'Rate' : rate})
        
        df = pd.DataFrame(values_list)
        excel_file_path = os.path.join(BASE_DIR, 'SGDToUSD.csv')
        df.to_csv(excel_file_path, index=False)
        print("Данные сохранены в Excel файл")
    except Exception as e:
        print("Ошибка: " , e)
else:
    print(f"Запрос завершился неудачей с кодом состояния {response.status_code}")

Я пытался загрузить страницу с помощью Selenium и использовать наведение мыши, чтобы получить точки данных, но это тоже не сработало.

Есть ли способ, с использованием или без использования Selenium, чтобы получить эти данные?

Ответ или решение

Для извлечения данных из динамического графика на сайте, таком как XE.com, необходимо использовать более продвинутые подходы, так как стандартных HTTP-запросов может быть недостаточно для получения всех нужных данных.

Шаги для извлечения данных из динамического графика

  1. Анализ ответственности API:
    Вы правильно нашли URL-адрес для получения данных через API (https://www.xe.com/api/protected/charting-rates/?fromCurrency=SGD&toCurrency=USD&crypto=true). Однако, данные из этого API могут не полностью соответствовать тем, что отображаются на графике. Это связано с тем, что некоторые параметры (например, период времени) могут не передаваться в запросе.

  2. Использование самого сайта:
    Так как вы упомянули, что время отображается на графике, и при изменении периода времени происходит сетевой запрос, можно попробовать использовать Selenium для имитации действий пользователя. Поскольку API не предоставляет нужные данные, этот подход может быть более продуктивным.

  3. Установка Selenium:
    Убедитесь, что у вас установлен Selenium и соответствующий веб-драйвер для браузера. Например, для Chrome:

    pip install selenium

    Загрузите Chromedriver, совместимый с вашей версией Chrome, с официального сайта.

  4. Скрипт для извлечения данных:

    Вот пример, как можно реализовать скрипт на Python с использованием Selenium для извлечения данных:

    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    import pandas as pd
    
    # Инициализация драйвера
    driver = webdriver.Chrome(executable_path='path_to_chromedriver')
    driver.get("https://www.xe.com/currencycharts/?from=SGD&to=USD&view=5Y")
    
    # Ожидание загрузки элементов графика
    WebDriverWait(driver, 20).until(
       EC.presence_of_element_located((By.CLASS_NAME, "chart-data")))
    
    # Пример извлечения значений из графика
    chart_data = driver.find_elements(By.CLASS_NAME, "chart-data")
    values_list = [{'Date': data.get_attribute('data-date'), 'Rate': data.get_attribute('data-rate')} for data in chart_data]
    
    # Сохранение данных в CSV
    df = pd.DataFrame(values_list)
    df.to_csv('SGDToUSD_selenium_data.csv', index=False)
    print("Данные сохранены в файл")
    
    driver.quit()

Важные моменты:

  1. Изменение временного периода: В зависимости от того, как реализован интерфейс, возможно, потребуется автоматизировать процесс выбора различных периодов времени и ждать обновления данных.

  2. Проверка специфики данных: Убедитесь, что извлекаемый набор данных соответствует всем вашим требованиям и точно соответствует данным, которые отображаются на графике.

  3. Изучение структуры страницы: Если извлекаемые данные недостаточны, возможно, вам нужно будет дополнительно исследовать структуру страницы через инструменты разработчика, чтобы найти дополнительные элементы, которые могут содержать нужные данные.

  4. Оптимизация запросов: Если у вас есть возможность использовать API, хотя бы для первичных данных, это может ускорить процесс, так как в большинстве случаев они предоставляют более структуированные данные.

Следуя этим шагам, вы сможете извлечь необходимые данные из динамического графика на сайте XE.com.

Оцените материал
Добавить комментарий

Капча загружается...