Практические учебные задачи на Python: от парсинга до графиков

Раздел: Python -> Учебные задачи

Реализация прикладной задачи на Python

Рассмотрим типовую прикладную задачу: получение курсов валют с сайта Центрального банка России (ЦБ РФ) и сохранение данных в формате CSV. Данная задача демонстрирует работу с HTTP-запросами, парсинг XML, обработку данных и запись в файл. В зависимости от требований к производительности, сложности кода и необходимости дальнейшего анализа можно выбрать различные подходы.

Как наиболее эффективно получить курсы валют и сохранить в CSV с помощью pandas?

Основное решение использует библиотеки requests (или urllib) и pandas. Pandas умеет напрямую читать XML-файл из интернета и преобразовывать его в DataFrame, после чего легко сохранить в CSV. Этот подход минимален по объему кода и подходит для дальнейшего анализа данных.

import pandas as pd
import requests

# URL XML с курсами валют ЦБ РФ на текущую дату
url = 'http://www.cbr.ru/scripts/XML_daily.asp'

# Чтение XML напрямую из ответа сервера
response = requests.get(url)
data = pd.read_xml(response.text, xpath='.//Valute')

# Выбор нужных столбцов (например, CharCode, Name, Value)
df = data[['CharCode', 'Name', 'Value']]

# Сохранение в CSV
df.to_csv('currency_rates.csv', index=False, encoding='utf-8')
print('Данные сохранены в currency_rates.csv')

алгоритм решения задачи python (алгоритм решения задачи на python)

Данные сохранены в currency_rates.csv

базовые задачи python (базовые задачи python)

Проблемы: pandas может не установиться в окружении (тогда необходимо установить: pip install pandas openpyxl). Если сайт ЦБ временно недоступен, возникнет ошибка соединения. Рекомендуется добавить обработку исключений. Также XML может содержать символы, требующие корректной настройки кодировки (обычно windows-1251), но requests корректно обрабатывает ответ.

Как выполнить парсинг XML вручную с использованием встроенных средств?

Если установка pandas нежелательна, можно использовать модуль xml.etree.ElementTree и csv. Этот вариант даёт полный контроль над процессом извлечения данных.

import xml.etree.ElementTree as ET
import csv
import urllib.request

url = 'http://www.cbr.ru/scripts/XML_daily.asp'

# Получение XML
response = urllib.request.urlopen(url)
tree = ET.parse(response)
root = tree.getroot()

# Создание CSV и запись заголовков
with open('currency_rates_manual.csv', 'w', newline='', encoding='utf-8') as f:
    writer = csv.writer(f)
    writer.writerow(['CharCode', 'Name', 'Value'])
    
    # Обход всех элементов Valute
    for valute in root.findall('Valute'):
        char_code = valute.find('CharCode').text
        name = valute.find('Name').text
        value = valute.find('Value').text.replace(',', '.')
        writer.writerow([char_code, name, value])

print('Данные сохранены в currency_rates_manual.csv')

задачи для обучения python (задачи для обучения python)

Типичные ошибки: замена запятой на точку у числа (Value приходит с запятой). Необходимо учитывать, что теги Valute могут быть вложенными в ValCurs. Также возможна ошибка при отсутствии интернета. Код не обрабатывает ситуации, когда структура XML изменилась (например, добавлены новые теги).

Как использовать библиотеку lxml для ускорения парсинга?

Библиотека lxml предоставляет более быструю и гибкую обработку XML по сравнению со стандартным ElementTree. Она поддерживает XPath и удобную запись.

from lxml import etree
import csv
import requests

url = 'http://www.cbr.ru/scripts/XML_daily.asp'
response = requests.get(url)
root = etree.fromstring(response.content)

with open('currency_rates_lxml.csv', 'w', newline='', encoding='utf-8') as f:
    writer = csv.writer(f)
    writer.writerow(['CharCode', 'Name', 'Value'])
    for valute in root.xpath('//Valute'):
        char_code = valute.xpath('CharCode/text()')[0]
        name = valute.xpath('Name/text()')[0]
        value = valute.xpath('Value/text()')[0].replace(',', '.')
        writer.writerow([char_code, name, value])

Необходимо установить lxml (pip install lxml). Если сайт возвращает данные в кодировке windows-1251, lxml может интерпретировать их неправильно; рекомендуется указать кодировку явно: response.encoding = 'cp1251'.

- задачи на модули python (задачи на модули в python)
- задачи на операторы в python (задачи на операторы в python)
- задачи на последовательности python (задачи на последовательности в python)

Расширенные примеры использования

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

Асинхронное получение курсов с нескольких сайтов

Для одновременного опроса нескольких источников (например, ЦБ РФ и другого агрегатора) применяется модуль aiohttp. Собранные данные объединяются в один CSV.

Пример
import asyncio
import aiohttp
import pandas as pd

async def fetch_currency(session, url, name):
    async with session.get(url) as response:
        text = await response.text()
        # Предполагаем, что каждый источник возвращает XML/JSON
        # Здесь упрощённый пример для ЦБ РФ
        df = pd.read_xml(text, xpath='.//Valute')
        return name, df[['CharCode', 'Name', 'Value']]

async def main():
    urls = {
        'cbr': 'http://www.cbr.ru/scripts/XML_daily.asp',
        # другой источник
    }
    async with aiohttp.ClientSession() as session:
        tasks = [fetch_currency(session, url, name) for name, url in urls.items()]
        results = await asyncio.gather(*tasks)
        
    all_data = []
    for source, df in results:
        df['Source'] = source
        all_data.append(df)
    combined = pd.concat(all_data, ignore_index=True)
    combined.to_csv('multi_currency.csv', index=False)
    print('Сохранено multi_currency.csv')

if __name__ == '__main__':
    asyncio.run(main())
Сохранено multi_currency.csv

Такой подход полезен при сборе данных из нескольких источников без блокировки ввода-вывода.

Сохранение в Excel с форматированием

Иногда требуется не только CSV, но и Excel с цветными ячейками. Используется библиотека openpyxl.

Пример
import pandas as pd
from openpyxl import Workbook
from openpyxl.styles import PatternFill

url = 'http://www.cbr.ru/scripts/XML_daily.asp'
df = pd.read_xml(url, xpath='.//Valute')
df = df[['CharCode', 'Name', 'Value']]

# Создание Excel
with pd.ExcelWriter('currency_rates.xlsx', engine='openpyxl') as writer:
    df.to_excel(writer, sheet_name='Курсы', index=False)
    
    # Форматирование через openpyxl
    workbook = writer.book
    worksheet = writer.sheets['Курсы']
    fill = PatternFill(start_color='FFFF00', end_color='FFFF00', fill_type='solid')
    for cell in worksheet[1]:
        cell.fill = fill

print('Данные сохранены в currency_rates.xlsx')

Автоматический запуск по расписанию

Для ежедневного обновления курсов можно использовать библиотеку schedule.

Пример
import schedule
import time
import pandas as pd

def job():
    url = 'http://www.cbr.ru/scripts/XML_daily.asp'
    df = pd.read_xml(url, xpath='.//Valute')
    df[['CharCode', 'Name', 'Value']].to_csv('currency_daily.csv', index=False)
    print(f'{time.strftime("%Y-%m-%d %H:%M")} - Данные обновлены')

schedule.every().day.at('12:00').do(job)

while True:
    schedule.run_pending()
    time.sleep(1)

Скрипт будет запускаться каждый день в 12:00. Для работы в фоне можно использовать cron (Linux) или планировщик задач (Windows).

Визуализация курсов с помощью Matplotlib

После накопления исторических данных можно построить график изменения курса.

Пример
import matplotlib.pyplot as plt
import pandas as pd

# Предполагается, что ранее сохранён файл с историей currency_history.csv
df = pd.read_csv('currency_history.csv', parse_dates=['Date'])
usd = df[df['CharCode'] == 'USD']

plt.plot(usd['Date'], usd['Value'], marker='o')
plt.title('Курс доллара по дням')
plt.xlabel('Дата')
plt.ylabel('Курс (руб)')
plt.grid(True)
plt.savefig('usd_plot.png')
plt.show()

Для корректного отображения дат их необходимо преобразовать в datetime. Если данные собираются в реальном времени, возможны пропуски – их нужно интерполировать.

Прикладные задачи на Python - comments

En
прикладные задачи python (python)