Парсинг и обработка данных с метеосайтов Яндекс.Погода и Метеоинфо (Гидрометцентр) при помощи pandas (Часть 1)

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Всех приветствую! Хочу рассказать, как мне удалось примененить библиотеку pandas для парсинга и обработки метеорологических данных сайта Яндекс.Погоды. Отмечу, что это моя первая статья для Habr, строго не судите.

Краткая предыстория. Так случилось, что мне пришлось вести telegram-канал о погоде, практически сразу встал вопрос как сократить время на поиск и анализ данных с основных метеорологических сайтов, чтобы получать всё just-in-time на свой компьютер. Иными словами, была цель сделать небольшую автоматизацию. 

Яндекс.Погода

В настоящий момент существует некоторое количество стандартных методик получения данных с сайта (библиотеки requests), но мне удалось воспользоваться встроенным методом read_html() из библиотеки pandas и «прочитать» HTML-таблицу сразу в DataFrame, использую Jupiter Notebook.

Базовый синтаксис метода:

df = pd.read_html('ссылка')
Результат применения метода read_html() библиотеки pandas
Результат применения метода read_html() библиотеки pandas

Отдельно отмечу, что при чтении методом read_html() не улавливала ошибки при помощи конструкции try - except, так как, во-первых сам сайт Я.Погоды работает достаточно стабильно, а, во-вторых, цель была лишь получить данные.

Итак, после анализа полученной таблицы, стало очевидно, что необходимые нам данные лежат в ячейках [1]-[9]. Собираем их в DataFrame, с которым можно работать при помощи concat():

ya_new=pd.concat([ya_df[0],ya_df[1],ya_df[2],ya_df[3],ya_df[4],ya_df[5],ya_df[6],ya_df[7],ya_df[8],ya_df[9]],ignore_index=True)

Получаем таблицу с «сырыми» данными:

таблица с "сырыми" данными Яндекс.Погоды
таблица с "сырыми" данными Яндекс.Погоды

Ситуация стала лучше! Было заметно, что данные организованы достаточно структурно, отсутствуют пропуски в основных столбцах, соответсвенно появился некоторый план дальнейшей работы:

  1. Обработать столбец с температурой temp, чтобы получить нижнюю и верхнюю границу температуры при помощи регулярных выражений (и небольшой магии)

  2. Обработать столбец wind при помощи регулярных выражений, чтобы получить значение ветра (без направления)

  3. Придумать и реализовать обработку колонки с температурой по ощущениям (метеорологи называют ее) t_eff

  4. Собрать всё в итоговый датафрейм.

Обработка столбца temp заключалась в том, чтобы пройдя циклом построчно в столбце датафрейма, найти и записать в список элементы, соответствующие шаблону '[+ -]\d{1,2}\…[+ -]\d{1,2}'. Как следует разобраться в регулярках мне помогло это видео.

for i in range(0,ya_new.shape[0]):
    t_str=ya_new['temp'][i]
    temp_str=re.search(r'[+ -]\d{1,2}\…[+ -]\d{1,2}',t_str) #поиск по шаблону при помощи метода search() библиотеки re
    temp_clean.append(temp_str.group(0))

Аналогичным образом был реализован цикл для обработки столбца wind:

for i in range(0,ya_new.shape[0]):
    w_str=ya_new['wind'][i]
    wind_str=re.search(r'\d{1,2},\d',w_str) #поиск по шаблону при помощи метода search() библиотеки re
    wind_clean.append(wind_str.group(0))

Хотелось бы остановиться на обработке столбца t_eff. Столбец содержит строку, в которой дважды повторено одно и то же значение. В начале каждой такой строки может стоять «+», «-» либо ничего (если значение температуры 0). Реализация разделения:

t_eff=[]
for i in range(0,ya_new.shape[0]):
    string=ya_new['t_eff'][i]                 #идём по элементам столбца
    
    if string[0]=='−':                        #если сначала идет «-»
        s_1=re.sub('[^0-9]','', string)       #удаляем все, что не цифра
  
        s_fin='−'+s_1[:len(s_1)//2]           #сохраняем в новую строку «половину» длины строки со знаком «-»
    if string[0] != '−':                      #аналогично делаем для ситуации, если там не «-», а «+» или ничего.
        s_1=re.sub('[^0-9]','', string)
        s_fin=s_1[:len(s_1)//2]
    t_eff.append(s_fin)

Отдельно было заменен знак % в столбце влажности и обработаны типы данных и добавлен столбец со средней температурой:

#поработаем с форматами
ya_full[['t_down','t_up','wet']]=ya_full[['t_down','t_up','wet']].astype('int')
ya_full['wind']=ya_full['wind'].astype('float')
ya_full['t_eff']=ya_full['t_eff'].astype('int')

#считаем среднюю температуру
ya_full['t_mean']=(ya_full['t_up']+ya_full['t_down'])/2

...и собран итоговый датафрейм при помощи concat():

ya_full=pd.concat([list_days,temp_fin,ya_new[['press','wet']],wind_fin,temp_eff,ya_new['weather']],axis=1)
Итоговый результат обработки данных сайта Яндекс.Погода
Итоговый результат обработки данных сайта Яндекс.Погода

С такой табличкой уже можно было что угодно: считать средние по разным сайтам, строить графики, анализировать и т.д. В следующей статье расскажу про обработку данных сайта Гидрометцентра (там всё оказалось сложнее), полный код реализации из данного кейса можно посмотреть на моём github.

Источник: https://habr.com/ru/articles/733462/


Интересные статьи

Интересные статьи

Доброе время суток, уважаемое Хабр коммьюнити. В этой публикации я хотел бы показать несколько известных мне подходов к версионной миграции данных в контексте DTO. Примеры будут продемонстрированы на ...
Помню, недавно выполнял задание на вакансию масленка после технического собеседования и открыл для себя порт Faker API на .net. Отличная библиотека для генерации тестовых объектов по моделям.
Пожалуй, нет ни одной крупной IT компании, которая бы не страдала от огромного и неповоротливого legacy, состоящего из тесно переплетенных между собой решений. Каждое решение связано с несколькими дру...
В данной статье я расскажу о том, как правильно оформить документы, подтверждающие исключительные права ("право собственности") работодателя на произведение. Под произведением имею ввиду программы для...
В большинстве серверов HPE имеется встроенный контроллер управления Integrated Lights Out (iLO). Его первоначальное назначение – удаленное управление сервером: включение/...