Подтвердить что ты не робот

Извлечение информации веб-страницы на основе шаблона в Java

Сейчас я использую Jsoup, чтобы извлечь определенную информацию (не весь текст) с некоторых сторонних веб-страниц, периодически делаю это. Это отлично работает до тех пор, пока HTML-код определенной веб-страницы не изменится, это изменение приведет к изменению существующего Java-кода, это утомительная задача, потому что эта веб-страница изменяется очень часто. Также требуется программист исправить код Java. Вот пример кода HTML моего интереса на веб-странице:

<div>
<p><strong>Score:</strong>2.5/5</p>
<p><strong>Director:</strong> Bryan Singer</p>
</div>
<div>some other info which I dont need</div>

Теперь вот что я хочу сделать, я хочу сохранить эту веб-страницу (файл HTML) локально и создать из нее шаблон, например:

<div>
<p><strong>Score:</strong>{MOVIE_RATING}</p>
<p><strong>Director:</strong>{MOVIE_DIRECTOR}</p>
</div>
<div>some other info which I dont need</div>

Наряду с фактическими URL-страницами веб-страниц эти шаблоны HTML будут являться вкладом в программу Java, которая будет определять местоположение этих предопределенных ключевых слов (например, {MOVIE_RATING}, {MOVIE_DIRECTOR }) и извлеките значения из фактических веб-страниц.

Таким образом, мне не пришлось бы изменять программу Java каждый раз, когда изменится веб-страница, я просто сохраню HTML-страницу и заменю данных этими ключевыми словами, а отдых позаботится о программе. Например, в будущем фактический HTML-код может выглядеть так:

<div>
<div><b>Rating:</b>**1/2</div>
<div><i>Director:</i>Singer, Bryan</div>
</div>

и соответствующий шаблон будет выглядеть так:

<div>
<div><b>Rating:</b>{MOVIE_RATING}</div>
<div><i>Director:</i>{MOVIE_DIRECTOR}</div>
</div>

Также создание таких шаблонов может быть сделано не программистом, любым, кто может редактировать файл.

Теперь возникает вопрос: как я могу достичь этого в Java и есть ли какой-либо существующий и лучший подход к этой проблеме?

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

4b9b3361

Ответ 1

Подход, который вы дали, в значительной степени похож на Гилберта, кроме часть регулярного выражения. Я не хочу входить в уродливый мир регулярных выражений, я планирование использования шаблонного подхода для многих других областей, кроме информация о фильме, например. цены, извлечения продуктов и т.д.

  • Образец, который вы описываете, на самом деле не является "шаблоном" в обычном смысле слова: статическим контентом, который сбрасывается на выходе с кучей динамического содержимого, вставленного в него. Вместо этого он является "обратным" шаблоном - это шаблон разбора, который разворачивается и отбрасывается, оставляя нужные параметры.

  • Поскольку ваши веб-страницы меняются регулярно, вы не хотите жестко кодировать контент, который нужно проанализировать слишком точно, но хотите "увеличить масштаб" своих "важных функций", сделав минимум допущений. то есть вы хотите зафиксировать буквально соответствующий ключевой текст, такой как "Рейтинг", и обрабатывать разметку чередования, такую ​​как "<b/>", в гораздо более гибкой манере - игнорировать ее и позволять ей изменять без нарушения.

  • При объединении (1) и (2) вы можете дать результат любому имени, которое вам нравится, но это синтаксический анализ с использованием регулярных выражений. т.е. подход к шаблону - это подход синтаксического анализа с использованием регулярного выражения - они одно и то же. Возникает вопрос: в какой форме должно принимать регулярное выражение?

    3A. Если вы используете java-кодирование для синтаксического анализа, то очевидным ответом является то, что формат регулярного выражения должен быть только форматом java.util.regex. Все остальное является бременем развития и является "нестандартным", и его будет сложно поддерживать.

    3B. Если вы используете хотите использовать синтаксический анализатор, ориентированный на html, то jsoup является хорошим решением. Проблема в том, что вам нужно больше обработки текста и регулярных выражений и гибкости, чем кажется jsoup. Он кажется слишком запертым в определенные html-теги и структуры и поэтому ломается при смене страниц.

    3C. Вы можете использовать гораздо более мощный общий синтаксический анализатор, основанный на грамматике, такой как ANTLR - форма грамматики backus-naur, используемая для управления синтаксическим разбором, и код генератора вставляется для обработки анализируемых данных. Здесь выражения грамматики синтаксического анализа могут быть очень эффективными со сложными правилами для того, как текст упорядочен на странице и как текстовые поля и значения относятся друг к другу. Мощность не соответствует вашим требованиям, потому что вы не обрабатываете язык. И не избежать того факта, что вам все равно нужно описать уродливые биты, чтобы пропустить - например, метки разметки и т.д. И борьба с ANTLR впервые предполагает инвестиции в образование, прежде чем вы получите окупаемость производительности.

    3D. Есть ли Java-инструмент, который просто использует простой подход типа шаблона, чтобы дать простой ответ? Ну, поиск в google не дает слишком большой надежды https://www.google.com/search?q=java+template+based+parser&ie= UTF-8 & ОЕ = UTF-8 & водн = т & RLS = org.mozilla: ан-ГБ: официальный & клиент = светлячок-а. Я считаю, что любая попытка создать такого зверя будет дегенерировать либо в базовом анализе регулярных выражений, либо в более расширенном анализе, контролируемом грамматикой, потому что основные требования для сопоставления/игнорирования/замены текста приводят решение в этих направлениях. Все остальное было бы слишком просто, чтобы на самом деле работать. Извините за негативный взгляд - он просто отражает проблемное пространство.

Мое голосование за (3A) как простейшее, самое мощное и гибкое решение ваших потребностей.

Ответ 2

На самом деле это не шаблонный подход, но jsoup все же может быть работоспособным решением, если вы просто внесите экстренный запрос Selector в файл конфигурации.

Ваш не-программист даже не должен видеть HTML, просто обновите селектора в файле конфигурации. Что-то вроде SelectorGadget упростит выбор того, какой селектор действительно использует.

Ответ 3

Как я могу достичь этого в Java и существует ли какой-либо существующий и лучший подход к этой проблеме?

Шаблонный подход - хороший подход. Вы дали все причины, почему в вашем вопросе.

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

<div>
<p><strong>Score:</strong>{MOVIE_RATING}</p>
<p><strong>Director:</strong>{MOVIE_DIRECTOR}</p>
</div>

В принципе, вы должны использовать Jsoup для обработки ваших шаблонов. Затем, когда вы используете Jsoup для обработки веб-страниц, вы проверяете все обработанные шаблоны, чтобы увидеть, есть ли совпадение.

В совпадении с шаблоном вы найдете ключевые слова в обработанном шаблоне, затем вы найдете соответствующие значения на обрабатываемой веб-странице.

Да, это было бы много кодирования и сложнее, чем мое описание. Ваш Java-программист должен будет разбить это описание на более простые и простые задачи, пока он или она не смогут запрограммировать задачи.

Ответ 4

Если веб-страница часто изменяется, тогда вы, вероятно, захотите ограничить поиск полей, таких как MOVIE_RATING, до наименьшей возможной части страницы и игнорировать все остальное. Есть две возможности: вы можете использовать регулярное выражение для каждого поля, или вы можете использовать какой-то селектор CSS. Я думаю, что либо сработает, либо "шаблон" может состоять из простого списка поисковых выражений, регулярных выражений или css, которые вы бы применили. Просто просмотрите список и извлеките все, что вы можете, и выполните сбой, если какое-то определенное поле не найдено, потому что страница изменилась.

Например, регулярное выражение может выглядеть так:

"Score:"(.)*[0-9]\.[0-9]\/[0-9]

(Я не тестировал это.)

Ответ 5

Или вы можете попробовать другой подход, используя то, что я бы назвал "правилами" вместо шаблонов: для каждой части информации, которая вам нужна на странице, вы можете определить выражение jQuery, которое извлекает текст. Часто, когда изменение страницы невелико, те же хорошо написанные выражения jQuery будут давать те же результаты.

Затем вы можете использовать Jerry (jQuery в Java), с почти одинаковыми выражениями для получения текста, который вы ищете. Таким образом, это касается не только селекторов, но и других методов jQuery для хождения/фильтрации дерева DOM.

Например, правило для некоторого текста Director будет (в виде sudo-java-jerry-code):

$.find("div#movie").find("div:nth-child(2)")....text();

В правиле может быть больше (и более сложных) выражений, распространяемых по нескольким строкам, например, итерации некоторых узлов и т.д.

Если вы являетесь лицом ОО, каждое правило может быть определено в его собственной реализации. Если вы groovy человек, вы можете даже переписать правила, когда это необходимо, без перекомпиляции вашего проекта и все еще находящегося в java. Etc.

Как вы видите, основная идея здесь - определить правила, как найти свой текст; и не соответствовать шаблонам, поскольку это может быть хрупким для незначительных изменений. Представьте, что между двумя divs было добавлено просто пространство:). В этом примере я использовал синтаксис jQuery-like (на самом деле это синтаксис Jerry-alike, поскольку мы на Java) для определения правил. Это связано только с тем, что jQuery популярен и прост и известен вашему веб-разработчику; в конце вы можете определить свой собственный синтаксис (в зависимости от используемого вами инструмента синтаксического анализа): например, вы можете анализировать HTML в дереве DOM, а затем писать правила, используя ваши вспомогательные методы, как пройти по нему до места интереса. Джерри также предоставляет вам доступ к подстилающему дереву DOM.

Надеюсь, что это поможет.

Ответ 6

Я использовал следующий подход, чтобы сделать что-то подобное в личном проекте, который генерирует здесь RSS-канал ведущий сайт недвижимости в Испании.

Используя этот инструмент, я нашел арендованное место, в котором я сейчас живу; -)

  • Получить код HTML со страницы
  • Преобразование HTML в XHTML. Я использовал эту эту библиотеку Я предполагаю, что сегодня могут быть лучшие варианты
  • Используйте XPath для навигации по XHTML к интересующей вас информации.

Конечно, каждый раз, когда они меняют исходную страницу, вам придется изменить выражение XPath. Другой подход, который я могу придумать, - семантический анализ исходного HTML-источника, - далеко, далеко за пределами моих скромных навыков; -)