Время прочтения: 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)
Скрипт, позволяет сопоставить площадь уборки прилегающей территории с величиной снежного покрова. Перемножив имеющиеся данные, получили объем снега, требующий уборки на территории нужного объекта. Теперь эксперту осталось сверить оплаченные объемы с полученными данными и выявить аномальные отклонения, где суммы отличаются в несколько раз.
Данный подход позволил выявить такие нарушения как фальсификация документов на станциях приема и переработки снега, а также необоснованное увеличение объема убираемого снега за счет территорий, не принадлежащих обслуживаемым объектам.