Последнее редактирование — 12 марта 2025 года.
Предыстория:
У меня на домашнем ПК скопилось некоторое количество книг в электронном формате. Это в основной массе техническая литература. И мне хотелось всё это систематизировать. Придумывать не хочется, когда в книгах есть УДК, ББК классификаторы. Мне данная классификация в УДК очень даже подходит. А найти программу которая:
-
получит структуру УДК в виде иерархии
-
просканирует файлы pdf, и получит УДК коды
-
создаст по УДК кодам папки
-
переместит файлы в нужные папки
Этого всего я не нашел. Это лишь самое простое и базовое, что хотелось видеть. А еще хочется поиграться с названиями папок. Например после создания УДК структуры в каждой папке, создавать папку по расширению файла. Например PDF, DJVU. Или добавлять папку с годом книги и туда класть файлы. В общем вариантов много. И решил, что я буду писать небольшие консольные утилиты, которые сделают все это за меня.
Почему не все сразу? Все просто, вопрос во времени. Его как всегда нет, семья, работа, дети. А небольшие утилиты я могу попросить сгенерировать нейросеть, и быстенько проверить, что мне подходит.
Можете ругать меня, на чем белый свет стоит, за код. Я попытаюсь все замечания учесть и внести изменения. Идеи приветствуются.
Готовых таблиц я не нашел. Вероятно это связанно с авторскими правами. Поэтому будем получать таблицу сами.
Для частного использования полные таблицы не нужны. Мне нужны категории по IT, часть по разделам математики ну и пару разделов по философии и психологи.
Создаем maven проект
mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-simple -DarchetypeVersion=1.5
Вам будет предложено ввести groupId, artifactId, version, package
Define value for property 'groupId': ru.mcs.udk Define value for property 'artifactId': udk-site-parser Define value for property 'version' 1.0-SNAPSHOT: 1 Define value for property 'package' ru.mcs.udk: ru.mcs.udk Confirm properties configuration: groupId: ru.mcs.udk artifactId: udk-site-parser version: 1 package: jar Y: Y
Будет создан проект, который вы уже можете менять.
Добавляем зависимости pom.xml
Для получения данных с сайта я буду использовать jsoup.
<dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.15.3</version> </dependency>
Все лишнее можно удалить. У меня получилось так:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>ru.mcs.udk</groupId> <artifactId>udk-site-parser</artifactId> <version>1.0</version> <packaging>jar</packaging> <properties> <maven.compiler.source>21</maven.compiler.source> <maven.compiler.target>21</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <jar.finalName>udk-site-parser</jar.finalName> </properties> <dependencies> <dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.15.3</version> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-assembly-plugin</artifactId> <version>3.7.1</version> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <outputDirectory>${project.basedir}/jar</outputDirectory> <finalName>${jar.finalName}</finalName> <archive> <manifest> <addClasspath>true</addClasspath> <mainClass>ru.mcs.udk.UdkSiteParser</mainClass> </manifest> </archive> </configuration> <executions> <execution> <id>assemble-all</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
Плагин maven-assembly-plugin добавлен чтобы сгенерироть jar файл с jsoup в одной jar-ке.
Пишем код парсера
package ru.mcs.udk; import org.jsoup.Jsoup; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; import java.nio.charset.StandardCharsets; public class UdkSiteParser { public static final String HTTPS_WWW_TEACODE_COM_ONLINE_UDC = "https://www.teacode.com/online/udc"; public static void main(String[] args) throws IOException { System.setOut(new PrintStream(new FileOutputStream("udk.txt"), true, StandardCharsets.UTF_8)); getHierarchy(HTTPS_WWW_TEACODE_COM_ONLINE_UDC, 0, 15); } public static void getHierarchy(String url, int level, int stopLevel) { try { var document = Jsoup.connect(url) .timeout(5000) .followRedirects(true) .userAgent("Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0) Gecko/20100101 Firefox/25.0") .execute().parse(); Elements rows = document.select("table tr[bgcolor=#eaeaea]"); // тут создаем новую переменную которую будем передавать в метод int nextLevel = level + 1; for (Element row : rows) { Elements udkNumber = row.select("td:eq(0)"); Elements udkTitle = row.select("td:eq(1)[align=left]"); System.out.printf("%s%s\t%s%n", "\t".repeat(Math.max(0, level)), udkNumber.text(), udkTitle.text()); String pageUrl = udkNumber.select("a").attr("href"); if (!pageUrl.isEmpty() && level < stopLevel - 1) { String subUrl = getUrl(url, pageUrl); getHierarchy(subUrl, nextLevel, stopLevel); } } } catch (Exception ex) { System.out.println(ex.getMessage()); } } private static String getUrl(String url, String subUrl) { if (subUrl.startsWith(".")) { return String.format("%s%s", HTTPS_WWW_TEACODE_COM_ONLINE_UDC, subUrl.replaceFirst(".", "")); } else { return String.format("%s%s", url.replaceAll("/[^/]+\\.html$", "/"), subUrl); } } }
В строчке 17 мы переопределяем стандартный вывод в консоль на нужный нам файл.
Строчки 24-28 это получение странички. Таймаут 5 секунд. Можно увеличить если будут ошибки с таймаутами.
Строчка 30 это получение интересующих нас элементов в таблице. Определяется опытным путем.
Строчки 34-45 это сама логика получения уже нужных данных.
Метод getUrl используется для получения пути на подстраницу. Определяется опытным путем. Есть разница в путях на первой странице, поэтому такие условия.
Добавил параметр stopLevel, для того чтобы не получать всю иерархию. А только до определенного уровня. Это больше для тестирования. Выставил в 15 так как там, по моему, больше 10 уровня и нет.
Результат для 2 уровня вложенности получим примерно такой:
00Наука в целом (информационные технологии - 004) 001Наука в целом. Науковедение. Организация умственного труда 002Печать в целом. Документация. Научно-техническая информация (НТИ) 003Системы письма и письменности. Знаки и символы. Семиотика в целом. Коды. Графическое представление мысли 004Информационные технологии. Компьютерные технологии. Теория вычислительных машин и систем 005Изучение проблемы организации: методология, анализ, синтез, классификация и таксономия (теория, основы), систематизация в целом 006Стандартизация и стандарты 007Деятельность и организация. Общая теория информации, связи и управления (кибернетика), включая деятельность человека 008Цивилизация. Культура. Прогресс 009Гуманитарные науки в целом 1Философия. Психология 101Сущность и задачи философии 11Метафизика 122Причинность (каузальность). Первопричинность. Принципы. Causa efficiens. Условие. Действие. Побуждение ........... 9География. Биография. История 902Архелогия 903Предыстория. Доисторические остатки, орудия труда, древности. Интерпретация и синтез материальных остатков древнего человека, его культур и цивилизаций 904Археологические памятники исторических времен. Древности античного, средневекового и нового времени 908Краеведение 91География. Географические исследования Земли и отдельных стран. Путешествия. Региональная география 929Биографические и подобные исследования 93История. Теоретические вопросы 94Всеобщая история
Программа будет выполняться примерно пол часа. Можно открыть файл udk.txt и посмотреть заполняемость файла.
Собираем проект
mvn clean package
Запускаем проект
java -jar .\jar\udk-site-parser-jar-with-dependencies.jar
На этом все. Можно приступать к следующим шагам. Можно теперь парсить pdf и получать УДК. Создавать папки. При создании папок будут конечно проблемы, нужно будет убирать специальные символы. Но это уже другая история и в другой программе.
Код доступен тут: udk-site-parser
ссылка на оригинал статьи https://habr.com/ru/articles/890644/
Добавить комментарий