Практические учебные задачи на 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'.
Расширенные примеры использования
На основе рассмотренной задачи можно построить более сложные решения: асинхронный сбор данных, визуализацию, автоматизацию по расписанию и интеграцию с 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. Если данные собираются в реальном времени, возможны пропуски – их нужно интерполировать.