Так как песочницей для наших планов выступили Google Docs, а конкретнее Таблицы, то мне захотелось разместить фото всех чеков на отдельном листе. Первая попытка вставить картинку в таблицу через привычный пункт меню «Вставка > Изображение» привела к тому что чек оказался поверх ячеек таблицы и моим друзьям IT-шникам такое оформление точно бы не приглянулось:
«Должен же быть способ вставить картинку в ячейку...», — подумал я. Google нашел этот способ с первого запроса: функция IMAGE(URL), как значение ячейки. Ну что ж, дело сделано:
Можно дальше идти смотреть лыжные уроки. Хотя…
...Google моментально среагировал на мой запрос «Online FineReader API» и выдал несколько статей с хабра о ABBYY Cloud OCR SDK. Быстрый просмотр доступных методов платформы подтвердил мои надежды и желанный ocrsdk.com/documentation/apireference/processReceipt был найден. Для осуществления задуманного недоставало понимания как вставить в ячейку таблицы пользовательскую функцию, которая будет вызывать методы обработки чека. Но и тут поиск меня не подвел и был найден Редактор скриптов Google.
Теперь дело за малым. Первым делом необходимо создать приложение ocrsdk. Делается это в процессе регистрации нового пользователя, так что с этим проблем не возникло. Письмо с паролем приложения, который необходим для аутентификации запросов, было отправлено сразу после завершения регистрации.
Далее в нашей Таблице выбираем пункт меню «Инструменты > Редактор скриптов» и создаем функцию processReceipt(imageUrl):
function processReceipt(imageUrl) {
// Загружаем картинку чека
var image = UrlFetchApp.fetch(imageUrl);
// Формируем заголовок авторизации, который состоит из имени приложения и пароля
var pass = "GoogleDriveTest" + ":" + "********************"
// Формируем POST запрос на обработку чека
var url = "http://cloud.ocrsdk.com/processReceipt";
var headers = {
"Content-Type":"image/png",
"Authorization" : "Basic " + Utilities.base64Encode(pass)
};
var options = {
"method":"POST",
"headers": headers,
"payload" : image.getContent()
};
var response = UrlFetchApp.fetch(url, options);
// Парсим XML ответа и находим в нем ID задачи по обработке нашего чека (больше деталей тут http://ocrsdk.com/documentation/apireference/processReceipt/)
var document = XmlService.parse(response.getContentText())
var id = document.getRootElement().getChildren()[0].getAttribute('id').getValue()
var resultUrl
// Ждем успешного завершения задачи и получаем url по которому можно получить результат обработки чека
do {
Utilities.sleep(3000)
url = "http://cloud.ocrsdk.com/getTaskStatus" + "?taskId=" + id;
headers = {
"Authorization" : "Basic " + Utilities.base64Encode(pass)
};
options = {
"method":"GET",
"headers": headers,
};
response = UrlFetchApp.fetch(url, options);
document = XmlService.parse(response.getContentText());
if (document.getRootElement().getChildren()[0].getAttribute('status').getValue() == 'Completed') {
resultUrl = document.getRootElement().getChildren()[0].getAttribute('resultUrl').getValue()
break
}
} while(true)
// Получаем результат обработки чека
options = {
"method":"GET",
};
response = UrlFetchApp.fetch(resultUrl, options);
document = XmlService.parse(response.getContentText());
// document содаржит XML нашего чека. Из-за моральных принципов реализацию функции findTotalPriceInReceiptXML я скрыл :)
result = findTotalPriceInReceiptXML(document)
return result
}
Всё сохраняем и идем обратно в таблицу. Чтоб сие чудо заработало, пришлось вынести в отдельную ячейку таблицы URL картинки чека. Наша функция теперь доступна как =processReceipt(ячейка с URL).
Всем хорошей зимней погоды и удачи на лыжных склонах!
Комментарии (41)
DistortNeo
06.01.2017 19:30+3Что-то мне подсказывает, что просто вбить «134.36» руками было бы быстрее, чем фотографировать чек, вставлять его в документ и распознавать. Здесь нужно писать приложение для телефона, которое само фотографирует чек и распознаёт его.
vlad_br
06.01.2017 20:06Вы правы в том что приложение решит задачу организации базы фотографий чеков с их распознаванием более качественно. Более того, таких приложений написано предостаточно. А вот метод продемонстрированный в статье, хоть и не оптимален, но достаточно оригинален. Его плюс в том, что всё что вам надо сделать — написать логику по обработке изображения, а вот о визуальной составляющей уже позаботились инженеры google.
Leopotam
07.01.2017 01:00Проблема в том, что у каждого магазина свой чек и свой лейаут данных, часто с невообразимыми переносами. Буквально на днях решал такую же задачу — занесение данных с чеков в домашнюю бухгалтерию. Был написан бот в телеграме, который принимает потоком позиции расхода / прихода в виде «хлеб 123 еда» (товар, стоимость, категория), причем эти данные вносятся голосовым набором с мобильного устройства (распознавание идет средствами android / ios автоматически, распознанная команда отправляется как текст). Есть возможность посмотреть статистику за указанный год / месяц / день и выгрузить это все в виде csv, который уже потом можно залить в google docs и построить всевозможные графики. Жена говорит, что нравится и что стало гораздо удобнее заносить данные, чем вручную вбивать в таблицу.
vlad_br
07.01.2017 01:16+1Да, проделанная в статье работе не более чем демонстрация возможностей указанных технологий. Для серьезного дела я бы не рассчитывал на данный вид анализа. Плюс, сервис был очень удивлен, увидев польский чек, скажу я Вам.
Leopotam
07.01.2017 13:53+1То, что описал выше, выглядит примерно вот так:
Длинный скриншотsviterov
08.01.2017 01:34О, а не дадите ссылку на бота?
Leopotam
08.01.2017 11:14Он «приватный», т.е. будет отбивать всех пользователей не из разрешенного списка. Возможно, когда подчищу говнокод — выложу в паблик. Но там все просто на самом деле — nodejs + node-telegram-bot-api. Если сильно надо, то пишите, отдам так.
shasoft
07.01.2017 01:10Нужно оплачивать с карточки, тогда такое распознование не понадобится. :)
p.s.А есть вообще на Android приложения которые фоткают и распознают чеки? Искал пару лет назад — не нашел. Но может что-то уже появилось или искал плохо?Leopotam
07.01.2017 01:131. Не везде есть возможность выгрузки из ЛК банка
2. Не везде есть терминалы, часто требуют платить в кассу наличкой, например, на шиномонтаже в замкадье такое часто встречается.
3. Возможно карточек больше одной и они от разных банков — см. пункт 1 :)
Чеки являются универсальным носителем нужной информации, пусть и не унифицированной.webpavilion
07.01.2017 10:56Много лет пользуюсь одним из сервисов для ведения домашней бухгалтерии.
1. ЛК банка не нужен. Всё работает через СМС информирование о операциях по картам, на смартфоне в фоне приложение которое распознает и отправляет на сервер всё операции.
2. Живу в 80км от дефолтсити, 93% всех расходов с банковских карт.
3. Карт у меня 7 штук от 4 разных банков, в разных валютах, всё работает без каких либо проблем.
Чеки не удобны для долгосрочного хранения, нужно много места и уже через пару лет на них сложно что то разобрать.Leopotam
07.01.2017 13:35Чеки не удобны для долгосрочного хранения
Так и не нужно их хранить — внести данные и уничтожить. Тут проблема в том, что чеки у разных магазинов разные в плане размещения информации и сокращения наименований товаров — не получится простым способом решить распознавание данных в автоматическом режиме. Ну и отдавать данные в сторонний сервис не хотелось бы.
Всё работает через СМС информирование о операциях по картам, на смартфоне в фоне приложение которое распознает и отправляет на сервер всё операции.
Так приходит только общая сумма, а хотелось бы разбивку по категориям. Практически всегда категорий больше чем одна. Это нужно для дальнейшего анализа, на что было сколько потрачено за определенный период, графики, все дела.
93% всех расходов с банковских карт
Примерно так же, apple pay принимается практически в 100% терминалов (сбербанк постарался — обновил практически все терминалы), но все-равно приходится с собой таскать 2-3к наличкой.immaculate
07.01.2017 21:18+1На самом деле, как человек ведущий домашнюю бухгалтерию более 10 лет, скажу, что разбивка чека по категориям — не нужна. Зачем вам такая детализация? Какую полезную информацию вы получаете из такой детализации?
Мой опыт такой, что разбивка по массе узких категорий — это большие затраты труда, которые не приносят ощутимых дивидендов. Например, часто в супермаркете покупаю вместе с продуктами несколько журналов. Можно конечно каждый раз разбивать чек на две категории: продукты и журналы. На практике же, никакой пользы от такой разбивки нет. Что я, журналы вдруг перестану покупать. Я покупаю три журнала: «Мото», «Мотоэксперт» и «Наука и жизнь». Каждый год трачу на это приблизительно одинаковую сумму, в пределах 400-600 рублей в месяц. Зачем мне эта информация в отдельной категории?
Изначально я тоже пытался каждый чек бить и каждую категорию учитывать отдельно. Но это превращает учет в пытку, а пользы — ровно 0.
Leopotam
07.01.2017 22:20Это позволяет делать выборку по категориям по приходу / расходу. Возможно может показаться бесполезным, но это используется в дальнейшем при фильтрации для рисования графиков и прочего. Позволяет в размышлениях, что на что было потрачено. :)
immaculate
07.01.2017 22:35+1Ценность этой информации минимальна, на самом деле. И без того количество категорий достаточно большое, чтобы еще и чеки из супермаркета бить. Никакой информации для принятия решений из этого не извлечь.
Допустим, меня интересуют в домашнем учете следующие вопросы:
- сколько всего зарабатываю
- сколько всего трачу
- сколько денег у меня сейчас
- сколько трачу на какие-то регулярные повторяющиеся вещи: в среднем на продукты в месяц, на коммунальные услуги, на содержание авто и мотоцикла
Первые два вопроса — самые важные, так как позволяют принимать какие-то долгосрочные решения. Например, сколько в месяц я могу откладывать на какую-то очень большую затрату и сколько месяцев/лет мне понадобится (путешествие, новый мотоцикл, еще что-то из этой категории). Ответ на третий вопрос часто бывает нужен, чтобы принять решение о какой-то внезапной трате. Ответ на последний вопрос — чтобы скорректировать какие-то ежемесячные траты, например, на мобильную связь.
Большой уровень детализации возможно позволяет строить более красивые графики, но он очень быстро утомляет и забрасываешь ведение бухгалтерии вообще. А извлекаемая информация никогда не нужна, во всяком случае, мне. Конечно, у всех разные цели, мотивации, уровни доходов и расходов. Допустим, если бы доход у меня был в 10 раз выше, чем сейчас, я бы вообще не заморачивался, скажем, теми же расходами на мобильную связь.
Leopotam
07.01.2017 22:43Еще раз — эта информация важна в моем конкретном случае, даже если это не важно кому-то еще. Ну и это все автоматизировано — сказать одно короткое слово в конце фразы — ничего утомительного. Доход позволяет не думать о мелких расходах, но возможность разбивки по категориям ничего фактически не стоит в плане занесения, а так же было в списке требуемых фич в ТЗ основного пользователя — жены.
Spunreal
11.01.2017 00:30Например, потратил в магазине продуктовом 20к в месяц. Понял. что что-то многовато. Построил по категориям, выявил существенные расходы и выяснил, что оказывается каждый день покупалась баночка колы (вот просто так), а так же какой-то дорогой сырок, от которого ни холодно ни жарко, но который сожрал 2000р за месяц (а его аналог уже 1000 всего лишь). В итоге уже экономия в 2000 — 3000 рублей.
Вручную заносить действительно сложно, но когда есть автоматизированный инструмент, то почему бы и нет. Если бы по такой схеме (сколько всего зарабатываю / сколько всего трачу) работали в рекламных сетях, то все бы разорились. Сотни рекламных кампаний, тысячи объявлений, брать в расчёт нужно конкретное объявление или кампанию, а не весь аккаунт.
P.S. это естественно актуально до определённого уровня заработка. Дальше просто смысла нет пытаться сэкономить 5-10% (хотя кто знает). Но учитывая средний уровень заработка по России, то всем очень даже пригодится автоматическое разбиение по категории.
P.P.S. Таким образом можно избавить себя от внезапных ненужных трат — поход по магазинам, когда всё есть и выброс 5-10к на вещи. Поход куда угодно, что не особо то и нужно было. Как раз в этом случае детализация позволит выявить такие траты, а в сколько всего тратится будет только общая информация, но никак не полезность покупок или трат.DistortNeo
11.01.2017 01:51На эту тему есть хороший анекдот:
Стоит прилично одетый мужчина в Нью-Йорке возле небоскреба и курит.
Подходит к нему журналист и говорит:
— Здравствуйте. я корреспондент газеты «Нью-Йорк Таймс». Можно задать
вам несколько вопросов?
— Да задавайте, я в принципе не спешу.
— Вот вы курите. А, простите, как долго вы курите?
— Мне сейчас 43, и курю я с 16 лет.
— А какие сигареты вы курите, если не секрет?
— Да не секрет — «Мальборо».
— И последний вопрос — сколько сигарет в день?
— Пачки полторы — две.
Журналист достает калькулятор, что-то считает и снова обращается
к мужчине:
— Вот вы знаете, если бы вы не курили, то на сэкономленные деньги
вы могли бы купить вот этот вот небоскреб?
— Серьезно?.. А вот вы сами курите?
— Нет, я не курю.
— И что, небоскреб у вас есть?
— Нет, небоскреба у меня нет.
— А я курю, и небоскреб мой…
malbaron
11.01.2017 10:40Пример с едой показателен, но только для начала карьеры.
Я во время учебы в ВУЗе и сразу после окончания вел такую штуку…
В иные месяца:
50% уходило на аренду квартиры,
25% уходило на печенки и 25% уходило на пиво…
;)
Потом аналитику забросил, так как стало хвать как этому курящему мужику с небоскребом.
В середине декабря получил 270 тыс. руб.
Но они куда-то делись до 5 января (не пил).
Решил, что пора снова, как в студенческие годы, вести аналитику.
P.S.:
Все хорошо по ситуации.
Считать каждую булочку важно только когда ты студент.Leopotam
11.01.2017 11:07А еще можно просто ужасаться, куда делось 300к за 2 месяца, хотя вроде ничего такого серьезного не покупалось :) Статистика в первую очередь носит информационный характер, а принимаются решения или нет — это другой вопрос.
pyhtin
07.01.2017 13:321) У многих банков есть мобильные приложения, а они доступаются к данным через API, вот и получаем простой способ импортировать в свою систему все траты. Например вот https://rockapipreview.surge.sh/operations/, еще ковырялся в API tinkoff.ru, там тоже все просто. На 99% уверен что сбербанк, альфабанк, втб, юникредит тоже можно импортировать.
2) внести пару покупок в месяц руками не так сложно
3) см. п. 1Leopotam
07.01.2017 13:36См. комментарий выше — сумма, к сожалению, приезжает одним куском, без разбивки на товары.
bevice
07.01.2017 17:52Живу в замкадье, карточек много, разных банков, выводы такие:
Для покупок используется одна, с которой бонусы жирнее. Другие карты используются в особых случаях. И не представляю сценария, по которому я буду еду покупать сегодня с одной карты, а завтра с другой.
Шиномонтаж — в идеале это две операции в год. Я понимаю, что это пример, но основные расходы — это продукты/бензин/кафешки и прочие развлечения, которые оплачиваются картой. Несколько месяцев в кошельке лежали пара сотен рублей, пока не спустил на жетоны в автомойке, вот куда еще эквайринг не пришел, кстати.
Garrett
07.01.2017 17:53Наоборот!
Можно взять выписку из банка (желательно CAMT) и привязывать к расходам чеки!
andreyle
08.01.2017 16:16Попробуйте Office Lens (https://play.google.com/store/apps/details?id=com.microsoft.office.officelens&hl=ru) умеет исправлять перспективу документа и экспортировать в OneNote который уже в свою очередь распознает документ. Есть под все основные платформы.
ivanbolhovitinov
07.01.2017 05:37А в Казахстане многие (а может даже и все) кассы подвели к общей системе.
В чеке пишут URL и контрольный номер. Через сайт и контрольный номер можно этот чек пробить через сайт обратно: https://consumer.oofd.kz/.
Причем некоторые магазины предоставляют более подробную информацию о покупке чем другие (номенклатура).
Только как-то оно всё непонятно зачем. API нет, чтоб пробить чек надо вбить все данные (включая контрольный код, время и общую сумму). Видимо сделано, чтоб можно было убедиться, что магазин не скручивает чеки или другим способом уклоняется от уплаты налогов. И если покупатель чека не найдет в базе, то он может магазин заложить.BalinTomsk
07.01.2017 08:27В Канаде всего один магазин Home Depot разпознает дебитовую кароточку и посылает на зарегистрированный email версию чека
Morosus
07.01.2017 13:31Просто хочу напомнить, сто с 2017 года на территории РФ действует новая редакция ФЗ-54, согласно которой для большинства ритейл операций онлайн фискализация является обязательной. Так что теперь на чеке должен ьыть qr код со ссылкой на чек в электронном виде.
malbaron
08.01.2017 01:34То есть все магазины обязаны быть подключены к интернету?
И если интернет пропадает — продавать товары нельзя?Morosus
09.01.2017 18:55Да, за исключением «труднодоступных мест», список которых будет обудликован позднее, все должны иметь доступ к интернет. Если саязь разорвана, то продажи можно осущетвлять в течение определенного времени (в законе данный промежуток не указан, но производители оборудования ориентируются на приблизительно 30 дней), при восстановлении связи данные будут переданы Оператору Фискальных Данных
Sersoftin
09.01.2017 02:44Уже для всего сделали? Раньше точно было для некоторых видов алкоголя. На чеке выбивали qr код и сразу url, где можно было посмотреть все это.
Morosus
09.01.2017 18:52Да, теперь для практически всех видов товаров.
Исключение:банки, газетные киоски, обувные ателье, столовые в учебных учреждениях, пункты приема стеклопосуды и утильсырья, торговля на рынках и ярмарках, а также такие виды деятельности, как продажа ценных бумаг, продажа проездных билетов в общественном транспорте, торговля из автоцистерн, разносная торговля, изготовление и ремонт металлической галантереи и ключей, присмотр и уход за детьми, больными, престарелыми и инвалидами, продажа предметов народного художественного промысла
Stas911
09.01.2017 02:20По работе пользуемся сервисом Expensify для заполнения трат — там в мобильном клиенте есть такой функционал: сфоткал чек и готово.
playaaa
11.01.2017 00:30Как насчет просто воспользоваться Expensify, доступным для частным лиц по бесплатной подписке?
and7ey
Т.е. лишь 25 чеков можно распознать бесплатно. Печально.
and7ey
Хотя можно 100 страниц в месяц получить бесплатно — http://blog.ocrsdk.com/get-the-best-ocr-technology-for-free. Уже лучше :).
apelsyn
Если нужно поставить на поток попробуйте tesseract, там есть поддержка большого количества языков. Он, конечно же менее комфортен, но с подобным чеком справиться без поблем.
Недавно обновились натренированные модели для многих языков