Время прочтения: 3 мин.

В нашей стране, где зимний период в среднем составляет около 200 дней, уборка снега –важная и необходимая составляющая клининговых услуг. Большие объемы работы приводят к рискам нарушений, связанных с вывозимыми объемами. 

Обычно, проверка такого процесса заканчивается сравнением объемов вывоза и оприходования снега приемочной станцией. В нашем случае выявить отклонения таким образом не удалось. Документы в порядке. Но это не значит, что нужно остановиться, верно? Следует определить новые, интересные методы для поиска отклонений и, кажется, мы нашли такой. 

А что, если сравнить вывозимый объем снега с фактически выпавшим?  

Для реализации идеи в сети интернет были найдены данные с метеорологических станций по всему Миру. Выбранный ресурс — https://rp5.ru/Погода_в_мире. Сайт предоставляет возможность скачать архив с данными о погоде за выбранный период. Для этого нужно перейти по ссылке «Архив погоды» в нужном городе, далее перейти на вкладку «Скачать архив погоды», выставить нужный диапазон, выбрать удобный формат файла с архивом и нажать на кнопку «Выбрать в файл GZ (архив)». Давайте автоматизируем этот процесс с помощью библиотеки selenium: 

# selenium - для автоматизации наших действий в браузере 

# requests - для скачивания файла 

from selenium import webdriver 

import requests 

# ссылка на страницу с нужным населенным пунктом, в нашем случае — Н.Новгород 

URL  =  'https://rp5.ru/%D0%90%D1%80%D1%85%D0%B8%D0%B2_%D0%BF%D0%BE%D0%B3%D0%BE%D0%B4%D1%8B_%D0%B2_%D0%9D%D0%B8%D0%B6%D0%BD%D0%B5%D0%BC_%D0%9D%D0%BE%D0%B2%D0%B3%D0%BE%D1%80%D0%BE%D0%B4%D0%B5' 

# для селениума нужен driver web-браузера, прописываем к нему путь

DRIVER = 'driver/chromedriver' 

# за какой период нужны данные

START_DATE = '01.01.2020' 
END_DATE = '03.03.2020' 

# запускаем selenium, выставляем неявное ожидание и переходим на страничку с архивом

wd = webdriver.Chrome(DRIVER) 
wd.implicitly_wait(10) 
wd.get(URL) 

# здесь и далее для указания нужных элементов страницы 

# используются XPath 

# выделить нужный элемент -> Посмотреть код -> Copy -> Copy XPath 

# переходим по вкладке «Архив погоды» 

d_vkl = wd.find_element_by_xpath('//*[@id="tabSynopDLoad"]') 

d_vkl.click() 

# заполняем начальную и конечную даты 

start_date_input = wd.find_element_by_xpath('//*[@id="calender_dload"]') 
end_date_input = wd.find_element_by_xpath('//*[@id="calender_dload2"]') 

start_date_input.clear() 
start_date_input.send_keys(START_DATE) 

end_date_input.clear() 
end_date_input.send_keys(END_DATE) 

# выбираем формат файла (csv) и кодировку (utf-8) 

radio_csv = wd.find_element_by_xpath('//*[@id="toFileMenu"]/form/table[2]/tbody/tr[2]/td[3]/label/span') 
radio_csv.click() 

radio_utf = wd.find_element_by_xpath('//*[@id="toFileMenu"]/form/table[2]/tbody/tr[3]/td[3]/label') 
radio_utf.click() 

# нажимаем кнопку скачивания, чеез некоторое время появится ссылка на файл с архивом погоды 

download_button = wd.\ 

    find_element_by_xpath('//*[@id="toFileMenu"]/form/table[2]/tbody/tr[3]/td[6]/table/tbody/tr/td[1]/div/div') 

download_button.click() 

# скачиваем файл

download_link = wd.find_element_by_xpath('//*[@id="f_result"]/a') 
download_link_href = download_link.get_attribute("href") 

r = requests.get(download_link_href) 
open('file.csv','wb').write(r.content) 

# закрываем окно браузера

wd.close() 
print('Файл записан.') 

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

Далее, нам нужно сопоставить данные о погоде с площадью уборки объекта, предварительно избавившись от ненужных нам данных в архиве: 

# библиотека для работы с табличными данными 

import pandas as pd 

# читаем скачанный архив 

df = pd.read_csv("file.csv", header=6, encoding='utf-8',delimiter=',') 

# заменим название первого столбца, содержащего название населенного пункта 

new_columns = ['date', *df.columns[1:]] 
df.columns = new_columns 

# оставим только дату и толщину снежного покрова 

df = df[['date','sss']] 

# толщина снежного покрова замеряется только раз в сутки 

# но в течении одного дня остальные показатели снимают несколько раз 

# поэтому удаляем пустые поля в столбце ‘sss’ 

df = df.dropna() 

# сортируем по полю ‘date’ от более старой даты к новой 

df = df.sort_values('date') 

# открываем файл с графиком уборок объектов 

ub = pd.read_csv("nedv.csv") 

# сопоставляем архив погоды с графиком уборок по дате 

sq = pd.merge(ub,df) 

# добавляем поле объем снега, умножив площадь территории на высоту снега 

# не забудьте перевести в одну метрическую систему! 

sq['v'] = sq['sss']*sq['s'] 

# сохраняем получившийся файл для дальнейшего анализа экспертами 

sq.to_csv("uborka.csv",index=False) 

Скрипт, позволяет сопоставить площадь уборки прилегающей территории с величиной снежного покрова. Перемножив имеющиеся данные, получили объем снега, требующий уборки на территории нужного объекта. Теперь эксперту осталось сверить оплаченные объемы с полученными данными и выявить аномальные отклонения, где суммы отличаются в несколько раз.  

 Данный подход позволил выявить такие нарушения как фальсификация документов на станциях приема и переработки снега, а также необоснованное увеличение объема убираемого снега за счет территорий, не принадлежащих обслуживаемым объектам.