Погода в Python: скрейпинг и OpenWeatherMap
Python прост и гибок, поэтому многие используют его для сбора данных из интернета и создания полезных приложений. В этом материале вы научитесь получать актуальные погодные данные в реальном времени двумя способами и использовать их в простом погодном приложении.
Как это работает — кратко
- Веб-скрейпинг: отправляете HTTP-запрос к странице, парсите HTML и извлекаете нужные элементы (например, с помощью CSS-селекторов). Хорош для быстрого прототипа, но ненадёжен при изменениях страницы или ограничениях со стороны сервера.
- API: отправляете запрос на официальный сервис (JSON), получаете структурированный ответ. Требует API-ключа, стабилен и поддерживается поставщиком.
Определения в одну строку:
- Веб-скрейпинг — автоматизированный парсинг HTML для извлечения данных.
- API — программный интерфейс сервиса, возвращающий данные в формате (обычно) JSON.
Получение текущей погоды города с помощью веб-скрейпинга
Веб-скрейпинг — процесс извлечения данных и контента с веб-страницы. Многие источники публикуют данные в HTML, и их можно спарсить локально. Для задач парсинга HTML в Python часто используют библиотеку BeautifulSoup.
Установите зависимости (запустите в терминале):
pip install beautifulsoup4 requestsПосле установки импортируйте нужные пакеты (пример из проекта):
from bs4 import BeautifulSoup
import requestsВажно: некоторые сайты блокируют автоматические запросы, поэтому стоит указывать заголовки клиента (User-Agent), чтобы имитировать браузер:
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
}Создаём функцию для запроса к Google-поиску и парсинга результата. В примере используется CSS-селектор для извлечения местоположения, времени, описания и температуры:
def find_weather(city_name):
city_name = city_name.replace(" ", "+")
try:
res = requests.get(
f'https://www.google.com/search?q={city_name}&oq={city_name}&aqs=chrome.0.35i39l2j0l4j46j69i60.6128j1j7&sourceid=chrome&ie=UTF-8', headers=headers)
print("Loading...")
soup = BeautifulSoup(res.text, 'html.parser')
location = soup.select('#wob_loc')[0].getText().strip()
time = soup.select('#wob_dts')[0].getText().strip()
info = soup.select('#wob_dc')[0].getText().strip()
temperature = soup.select('#wob_tm')[0].getText().strip()
print("Location: " + location)
print("Temperature: " + temperature + "°C")
print("Time: " + time)
print("Weather Description: " + info)
except:
print("Please enter a valid city name")
Чтобы определить нужные ID элементов, выполните поиск в Google и откройте инструменты разработчика в браузере. Инспектируйте элементы и найдите селекторы, которые содержат данные (в примере используются #wob_loc, #wob_dts, #wob_dc, #wob_tm).
Метод select() применяет CSS-селектор к документу и возвращает все совпадения. getText() извлекает текст, strip() убирает лишние пробелы. После извлечения значения можно сохранять их в переменные и использовать в приложении или логике.
Пример запуска функции из консоли:
city_name = input("Enter City Name: ")
city_name = city_name + " weather"
find_weather(city_name)При запуске код запросит введение названия города. Если введён некорректный город или структура страницы изменилась, возникнет исключение — нужно обработать ошибки более аккуратно в боевом коде.
Важно:
- Веб-скрейпинг уязвим к изменениям разметки и политике сайта. Используйте его для прототипов или когда API недоступно.
- Уважайте правила robots.txt и условия использования сервисов.
Получение текущей погоды города с помощью OpenWeatherMap API
OpenWeatherMap — сервис, предоставляющий глобальные погодные данные через API: текущая погода, прогнозы, архивы. У бесплатного тарифа есть ограничения по количеству запросов (в исходном примере упомянуто 60 вызовов в минуту). Для работы нужен API-ключ: зарегистрируйтесь и получите его на странице My API Keys.
Не выкладывайте API-ключи в публичные репозитории. Для безопасности храните секреты в файлах окружения (.env) или в системах управления секретами.
Пример запроса и обработки ответа (оригинальный пример кода сохраняется):
# Importing libraries
import requests
import json
# Enter your OpenWeatherMap API key here
# DO NOT push it to a public repository
API_Key = "Your_API_Key"
# Provide a valid city name
city_name = input("Enter city name: ")
# Constructing the API URL path
url = f"http://api.openweathermap.org/data/2.5/weather?q={city_name}&appid={API_Key}"
# Making a get request to the API
response = requests.get(url)
# Converting JSON response to a dictionary
res = response.json()
# Uncomment the next line to see all
# data that are fetched from the API
# print(res)
# Checking if the city is found
# If the value of "cod" is not 404,
# that means the city is found
if res["cod"] != "404":
data = res["main"]
# Storing the live temperature data
live_temperature = data["temp"]
# Storing the live pressure data
live_pressure = data["pressure"]
desc = res["weather"]
# Storing the weather description
weather_description = desc[0]["description"]
print("Temperature (in Kelvin scale): " + str(live_temperature))
print("Pressure: " + str(live_pressure))
print("Description: " + str(weather_description))
else:
# If the city is not found,
# this block of code will be executed
print("Please enter a valid city name")
Примечания по OpenWeatherMap:
- По умолчанию температура приходит в Кельвинах. Чтобы получить градусы Цельсия или Фаренгейта, добавьте параметр units=metric или units=imperial к URL.
- API возвращает богатую структуру: main (temp, pressure, humidity), weather (описание и иконки), wind, sys (страна, sunrise/sunset) и т. д.
Пример преобразования температуры из Кельвина в Цельсий (дополнительный сниппет):
# Преобразование Кельвин -> Цельсий
kelvin = 300.15
celsius = kelvin - 273.15
print(f"{celsius:.1f} °C")Разработка простого погодного приложения — шаги
- Выбор источника данных: API (рекомендуется) или скрейпинг (быстро, но ненадёжно).
- Получение и обработка данных: парсинг JSON / HTML, валидация полей.
- Приведение единиц: температура, скорость ветра, время (таймзоны).
- Кэширование: чтобы не превышать лимиты API — локальный кэш на 1–10 минут.
- UI/CLI: консольный интерфейс, веб-приложение или мобильный клиент.
- Тестирование: юнит-тесты, интеграционные тесты запросов, обработка ошибок.
- Развертывание: хранение ключей в переменных окружения, логирование и мониторинг.
Короткая методология (микро-SOP):
- Для MVP используйте OpenWeatherMap с кэшированием на 5 минут.
- Валидация: проверяйте, что res[“cod”] == 200 и нужные поля присутствуют.
- При ошибке сети — возвращайте устаревшие данные из кэша и логируйте повторные попытки.
Практические подсказки и чек-листы
Чек-лист для разработчика:
- Получить API-ключ и добавить в .env (не в репозиторий).
- Обработать ошибки сети и неверные ответы API.
- Конвертировать единицы (K → °C или °F) и учитывать таймзоны.
- Добавить кэширование и ограничение частоты запросов.
- Написать тесты для основных сценариев (валидный/невалидный город, таймаут).
Чек-лист для DevOps/инфраструктуры:
- Хранение секретов в системе управления секретами.
- Настройка мониторинга лимитов API и алертов.
- Планы отката при изменении API-поставщика.
Чек-лист для продакшн-продукта (продуктовый менеджер):
- Список основных пользовательских историй (просмотр текущей погоды, прогноз, автопоиск по геолокации).
- Решение по офлайн/кэш-режиму.
- Политика частоты обновлений и ограничения.
Когда подходы не работают — ограничения и подводные камни
- Веб-скрейпинг ломается при изменении структуры страницы или при включении антибот-защиты (CAPTCHA, rate-limiting).
- Публичные API имеют лимиты, платные тарифы и требования к использованию данных (условия сервиса).
- Сетки часовых поясов и летнее время требуют корректной нормализации времени событий (sunrise/sunset, локальное время).
- Для высоконагруженных сервисов нужен мониторинг и балансировка, иначе вы быстро достигнете лимитов API.
Альтернативные подходы и инструменты
- Другие погодные API: Meteostat, Weatherbit, MeteoBlue — могут предлагать разные ограничения и модели ценообразования.
- Selenium/Playwright: если сайт активно использует JavaScript, можно рендерить страницу и парсить результат, но это дороже по ресурсам.
- Готовые SDK/клиенты: некоторые сервисы предлагают официальные клиентские библиотеки для удобства.
Безопасность и конфиденциальность
- Не храните API-ключи в публичных репозиториях. Используйте .env и переменные окружения.
- Логи не должны содержать ключи или персональные данные пользователей.
- Если собираете геолокацию пользователей, уведомьте их и соблюдайте требования конфиденциальности и локальные законы (например, GDPR для пользователей ЕС).
Критерии приёмки
- Приложение корректно извлекает и показывает погоду для заданного города.
- Обработаны ошибки: неверный город, отсутствие сети, превышение лимитов API.
- Температура отображается в выбранной пользователем единице (°C/°F).
- API-ключи и секреты безопасно хранятся вне репозитория.
Резюме
- Для быстрого прототипа можно использовать веб-скрейпинг (BeautifulSoup), но он ненадёжен для долгосрочных решений.
- Для стабильного сервиса лучше применять официальный API (например, OpenWeatherMap) и обрабатывать JSON-ответ.
- Добавьте кэширование, валидацию ответов и безопасное хранение ключей — это минимальные требования для боевого приложения.
Важно: исходный код проекта доступен в репозитории на GitHub и распространяется под лицензией MIT — проверяйте лицензионные условия перед коммерческим использованием.
Краткие выводы:
- Используйте API для надёжных данных.
- Веб-скрейпинг — быстрый путь, но требующий частого обслуживания.
- Безопасное хранение ключей и кэширование помогут избежать многих проблем.