{"id":34634436,"url":"https://github.com/spumer/tenzor-test","last_synced_at":"2026-05-26T22:32:48.189Z","repository":{"id":9929626,"uuid":"11943034","full_name":"spumer/tenzor-test","owner":"spumer","description":"Тестовое задание для компании Tenzor. Универсальный парсер контента, как правило нацеленный на новостные сайты.","archived":false,"fork":false,"pushed_at":"2013-08-09T08:00:37.000Z","size":220,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-13T02:03:07.775Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/spumer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-08-07T06:27:08.000Z","updated_at":"2017-12-15T20:29:04.000Z","dependencies_parsed_at":"2022-09-14T05:11:10.174Z","dependency_job_id":null,"html_url":"https://github.com/spumer/tenzor-test","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/spumer/tenzor-test","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spumer%2Ftenzor-test","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spumer%2Ftenzor-test/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spumer%2Ftenzor-test/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spumer%2Ftenzor-test/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/spumer","download_url":"https://codeload.github.com/spumer/tenzor-test/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spumer%2Ftenzor-test/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33542350,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"ssl_error","status_checked_at":"2026-05-26T15:22:15.568Z","response_time":63,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-12-24T16:59:34.786Z","updated_at":"2026-05-26T22:32:48.184Z","avatar_url":"https://github.com/spumer.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"tenzor-test\n===========\n\u003ch4\u003eТестовое задание для компании Tenzor. Универсальный парсер контента, как правило нацеленный на новостные сайты.\u003c/h4\u003e\n\n$ gcc -std=c99 -c trim.c\u003cbr\u003e\n$ g++ trim.o main.cpp -static-libgcc -std=c++11 -lstdc++ -lcurl -lxml2 -O2 -ffast-math -mfpmath=sse -fschedule-insns -fsched-pressure\n\n**Краткое описание.**\n\nЗа основу для алгоритма был взят популярный способ разметки сайтов: наличие блочного тега, содержимое которого оборачивается в строчные. На практике это выглядит след. образом: блочный тег \u0026lt;div\u0026gt;, строчные тег(и) \u0026lt;p\u0026gt;, \u0026lt;b\u0026gt;, \u0026lt;a\u0026gt; и т.д.\nДополнительным критерием оценки содержимого служит наличие ссылок, однако, вместо подсчета кол-ва ссылок ведется подсчет байт, которые они занимают. Тем самым позволяя обходить ленты новостей вида \u0026lt;a href=\"link to the page\"\u0026gt;Длинное название новости, почти краткое описание\u0026lt;/a\u0026gt;\u0026lt;a ...\u0026gt;Еще одна новость\u0026lt;/a\u0026gt;\n\n\n**Принцип работы.**\n\nПервым делом инициализируется список блочных/управляющих и строчных/дополнительных тегов. Анализ документа производится с помощью сторонней библиотеки libxml2, которой передается всего три callback'a: начало тега, получение данных, конец тега.\nДля определения в любой момент времени имени тега, с которым идет работа, оно помещается в стек(m_levelStack) при входе в тело тега и извлекается при выходе.\n\nРезультатом работы программы является список блочных тегов, из которого затем выбирается элемент с наибольшим размером.\n\nКогда обработчику встречается блочный тег, создается соответствующий объект типа Node и помещается в стек для временных объектов (m_parentStack) это позволяет сохранить порядок вложенности тегов, на случай если блочный тег вложен в блочный. \nДалее, при обработке строчных тегов их содержимое добавляется к предыдущему блочному тегу, уникальное поведение создано для ссылок: длина содержимого ссылки записывается в специальное значение m_Links, дабы в дальнейшем вычесть его из общего размера тега и тем самым свести к минимум влияние ссылок на основной контент.\nСодержимое тегов не указанных ни в одном из списков игнорируется.\nВ дополнение к основному фильтру, при добавлении контента происходит проверка глубины вложенности. Так, к примеру, тег оказавшийся слишком глубоко, за чередой неизвестных тегов будет проигнорирован. Подобное поведение присуще разного рода меню и лентам. Уровень вложенности изменяется только тегами, которых нет ни в одном из списков.\n\nПосле выхода из блочного тега, проверяется размер его содержимого. Пустые блочные теги уничтожаются. Остальные добавляются к результатам выборки.\n\n\n**Дальнейшее развитие.**\n\nВыделение \"словаря\" тегов во внешний источник, поддержка дополнительных списков для разных сайтов, имеющих отклонения в разметке.\nПроверка типа контента по ссылке, игнорирование изображений, видео и прочего.\nВедение лога своих действий в любой из приемников: master-server, файл, субд.\nИсправление допущений в коде, ошибок.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspumer%2Ftenzor-test","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fspumer%2Ftenzor-test","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspumer%2Ftenzor-test/lists"}