Собираем данные с чеков гипермаркетов на Python - LEFT JOIN

Свяжитесь с нами в любой удобной для вас форме

Менеджер

Написать в телеграмм

Онлайн
Телеграмм
или
Заполните форму

2 минут чтения

*

22 мая 2019 г.

Собираем данные с чеков гипермаркетов на Python

Update: к сожалению, информация в данном посте устарела. Рекомендуем изучить наш новый пост.

Недавно, покупая в очередной раз продукты в гипермаркете, вспомнил, что согласно ФЗ-54 любой оператор торговли, который пробивает кассовый чек, обязан отправлять данные чека в налоговую.

Чек из гипермаркета «Лента», QR-код, который нас интересует, обведен

Что это значит для нас, аналитиков данных? Что мы можем лучше узнать себя, свои потребности и получить интересные данные о собственных покупках.

Попробуем в рамках серии постов собрать небольшой прототип приложения, которое позволит строить динамику своих покупок. Итак, начнем с того, что в каждом чеке есть QR-code, если его распознать, то мы получим следующую строку:


t=20190320T2303&s=5803.00&fn=9251440300007971&i=141637&fp=4087570038&n=

В данной строке содержатся:
t — timestamp, время, когда вы осуществили покупку
s — сумма чека
fn — кодовый номер fss, потребуется далее в запросе к API
i — номер чека, он нам потребуется далее в запросе к API
fp — параметр fiscalsign, потребуется далее в запросе к API

В рамках решения первого шага нашей задачи мы будем парсить данные чека и собирать их в pandas dataframe, используя модули Python.

Мы воспользуемся API, который отдает данные по чеку с сайта налоговой.

В начале получим аутентификационные данные:



import requests

your_phone = ‘+7XXXYYYZZZZ’ #нужно указать ваш телефон, на него придет СМС с паролем

r = requests.post(‘https://proverkacheka.nalog.ru:9999/v1/mobile/users/signup’, json = {«email»:»email@email.com»,»name»:»USERNAME

В результате выполнения POST-запроса мы получим пароль в виде SMS на указанный мобильный телефон. Далее, мы будем использовать его в переменной pwd

Теперь распарсим нашу строку со значениями из QR-кода:


import re
qr_string=’t=20190320T2303&s=5803.00&fn=9251440300007971&i=141637&fp=4087570038&n=1′
t=re.findall(r’t=(w+)’, qr_string)[0]
s=re.findall(r’s=(w+)’, qr_string)[0]
fn=re.findall(r’fn=(w+)’, qr_string)[0]
i=re.findall(r’i=(w+)’, qr_string)[0]
fp=re.findall(r’fp=(w+)’, qr_string)[0]

Будем использовать полученные переменные для извлечения данных.

В посте на Хабре довольно подробно изучены статусы ошибок при формировании запроса к API, не буду повторять эту информацию.

В начале необходимо проверить, что по данному чеку есть данные, формируем GET-запрос.


headers = {‘Device-Id’:», ‘Device-OS’:»}
payload = {‘fiscalSign’: fp, ‘date’: t,’sum’:s}
check_request=requests.get(‘https://proverkacheka.nalog.ru:9999/v1/ofds/*/inns/*/fss/’+fn+’/operations/1/tickets/’+i,params=payload, headers=headers,auth=(your_phone, pwd))
printcheck_request.status_code)

В запросе необходимо указать headers, хотя бы пустые. В моем случае GET-запрос возвращает ошибку 406, из чего я понимаю, что такой чек находится (почему GET-запрос возвращает 406 для меня загадка, буду рад подсказкам в комментариях). Если не указать сумму или дату, то GET-запрос вернет ошибку 400 — bad request.

Переходим к самому интересному, получаем данные чека:


request_info=requests.get(‘https://proverkacheka.nalog.ru:9999/v1/inns/*/kkts/*/fss/’+fn+’/tickets/’+i+’?fiscalSign=’+fp+’&sendToEmail=no’,headers=headers,auth=(your_phone, pwd))
print(request_info.status_code)
products=request_info.json()

Чтобы работать с этими данными воспользуемся pandas и преобразуем все в dataframe.


import pandas as pd
from datetime import datetime
my_products=pd.DataFrame(products[‘document’][‘receipt’][‘items’])
my_products[‘price’]=my_products[‘price’]/100
my_products[‘sum’]=my_products[‘sum’]/100
datetime_check = datetime.strptime(t, ‘%Y%m%dT%H%M’) #((https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior отформатируем дату))
my_products[‘date’]=datetime_check
my_products.set_index(‘date’,inplace=True)

Теперь мы имеем рабочий pandas.dataframe с чеками, визуально это выглядит так:

«Шапка» чековых данных

Можно построить гистограмму покупок или посмотреть на все в виде «ящика с усами»:


import matplotlib.pyplot as plt

%matplotlib inline

my_products[‘sum’].plot(kind=’hist’, bins=20)

plt.show()

my_products[‘sum’].plot(kind=’box’)

plt.show()

В завершение элементарно получим описательные статистики в текстовом виде командой .describe():


my_products.describe()

Данные удобно записать в .csv-файл, чтобы в следующий раз дополнить статистику:


with open(‘hyper_receipts.csv’, ‘a’) as f:
my_products.to_csv(f, header=True)
499 просмотров

Комментарии

  • Виктор
    Виктор

    Работает ли данный способ на данный момент? Получается ли загружать чеки описанным способом? У меня работает только проверка существования чека, но при попытке загрузить чек запрос возвращает 202 без сообщений и любого содержимого.

    • Николай Валиотти
      Николай Валиотти

      Да, способ работает, только что проверил.
      А что отдает данная команда у вас: print(check_request.status_code)?

  • Виктор
    Виктор

    Вчера таки смог получить чеки. Видимо были какие то то трудности на стороне ФНС.
    «А что отдает данная команда у вас: print(check_request.status_code)?»
    Запрос существования чека возвращает 204, использую C# реализацию автора статьи на хабре, на которую вы ссылаетесь.

  • Николай Валиотти
    Николай Валиотти

    Хорошо, что все получилось!

  • Mihail Costa
    Mihail Costa

    Оба принта выдают 406, что не так?

    • Николай Валиотти
      Николай Валиотти

      Вроде бы все так, почему выдает 406-ую ошибку мне так и не удалось разобраться (об этом пишу в тексте).

      Пробовали этот код далее?

      request_info=requests.get(‘https://proverkacheka.nalog.ru:9999/v1/inns/*/kkts/*/fss/’+fn+’/tickets/’+i+’?fiscalSign=’+fp+’&sendToEmail=no’,headers=headers,auth=(your_phone, pwd))
      print(request_info.status_code)
      products=request_info.json()

  • Maslennikov Valentin
    Maslennikov Valentin

    406 возвращает потому что сумма в вашем примере должна быть передана как 580300, то есть копейки в одну строку с рублями

    • Николай Валиотти
      Николай Валиотти

      О, спасибо большое за комментарий!

  • etovityusha_hs
    etovityusha_hs

    При проверке наличия возвращает 204 (если добавить копейки в строку с рублями), но при запросе данных с чека возвращает 406 и непонятно что менять

  • Guest
    Guest

    там обновилось апи сегодня

    POST https://irkkt-mobile.nalog.ru:8888/v2/ticket HTTP/1.1
    Host: irkkt-mobile.nalog.ru:8888
    Accept: */*
    Device-OS: iOS
    Device-Id: B2462521-6CF4-4E1A-8AB2-477EF42CDB66
    If-None-Match: W/«39-v6LLCdIxNMpvWBhxOORTQGEZ2m8»
    clientVersion: 2.8.2
    Accept-Language: ru-RU;q=1
    Accept-Encoding: gzip, deflate, br
    sessionId: 5f1c54aed67b86d2dc6543ef:47044a6e-0956-41ef-912f-1c8a4f904451
    User-Agent: billchecker/2.8.2 (iPhone; iOS 13.5.1; Scale/3.00)
    Content-Length: 81
    Connection: keep-alive
    Content-Type: application/json

    {«qr»:«t=20200810T131800&s=346.77&fn=92804123123048&i=90192&fp=28121231230891&n=1»}

    HTTP/1.1 200 OK
    X-Powered-By: Express
    Content-Type: application/json; charset=utf-8
    Content-Length: 57
    ETag: W/«39-yMpfNJI5YltqpYIDvwSbW3LSdTQ»
    Date: Wed, 12 Aug 2020 04:43:34 GMT
    Connection: keep-alive

    {«kind»:«kkt»,«id»:«5f3373761231231230383f5»,«status»:0}

    GET https://irkkt-mobile.nalog.ru:8888/v2/tickets/5f337376d38b52fdf00383f5 HTTP/1.1
    Host: irkkt-mobile.nalog.ru:8888
    sessionId: 5f1c54aed67b86d2dc6543ef:47044a6e-0956-41ef-912f-1c8a4f904451
    Device-OS: iOS
    clientVersion: 2.8.2
    Device-Id: B2462521-6CF4-4E1A-8AB2-477EF42CDB66
    Accept: */*
    User-Agent: billchecker/2.8.2 (iPhone; iOS 13.5.1; Scale/3.00)
    Accept-Language: ru-RU;q=1
    Accept-Encoding: gzip, deflate, br
    Connection: keep-alive

    HTTP/1.1 200 OK
    X-Powered-By: Express
    Content-Type: application/json; charset=utf-8
    Content-Length: 1744
    ETag: W/«6d0-PNrWgcN+N3tbhG4U9VKmouk52v0»
    Date: Wed, 12 Aug 2020 04:43:35 GMT
    Connection: keep-alive

    данные чека

  • Николай Валиотти
    Николай Валиотти

    Спасибо большое за комментарий. Проверю работоспособность и обновлю статью!

    update: в итоге этой информации не хватило, чтобы собрать данные, но написали отдельный объект для получения нужных данных: http://leftjoin.ru/all/nalog-ru-client/

  • Антон
    Антон

    sessionId только не понятно откуда взять

  • Андрей Петров
    Андрей Петров

    Приветствую, коллеги. Аналогично столкнулись с изменением api налоговой. Сидели на нем. В поиске альтернативы обнаружили такой сервис: проверка чека http://proverkacheka.com/ Есть свое api (предоставляют по обращению), распознает QR-коды. На ура распознали и вернули все запрашиваемые чеки. Как вариант — рекомендую.

  • Николай Валиотти
    Николай Валиотти

    Коллеги, к сожалению, данный метод устарел, информация в комментариях ведет на внешние ресурсы.
    Новый метод, позволяющий получать данные, описан в новой заметке: http://leftjoin.ru/all/nalog-ru-client/

Добавить комментарий

[ Рекомендации ]

Читайте также

[ Дальше ]