LINUX.ORG.RU

Быстрый парсинг HTML

 


0

3

Представьте такую парсилку:

1. Сначала разобрать HTML-документ на линейную последовательность тегов. Линейную, карл. Никаких отношений между тегами. Парсер не знает про то, что теги вложены друг в друга, имеют закрывающих собратьев и другое. Тег - имя + набор атрибутов. Иерархии нет. Закрывающий тег - тупо отдельное имя в той же плоской последовательности. Есть тег «TD», а есть тег «/TD», у них просто вот такие имена и парсеру неважно почему они такие. Какой-нибудь простой текст будет в итоге превращён в объект-тег типа «TEXT» с атрибутом value равный самому тексту, допустим.

2. Рассмотреть всю эту последовательность как строку, где вместо char объект «тег» (с атрибутами).

3. Сделать как-бы regexp-машинку, но не совсем regexp: она оперирует не символами текста (char), а этими самыми объектами-тегами, линейно следующими, как обычный текст.

В таком духе:

// заматчить любую пару тегов <TD> + </TD> с любыми тегами между ними.
// повторю: здесь всем пофиг на имена тегов. Никаких отношений между TD и /TD парсер HTML и данная regexp-машина не знают. Для неё это просто 2 каки-то там тега.
TD, * *, /TD


// то же самое, но только <TD> имеющий атрибут "hello" равный 123
TD hello=="123", * *, /TD

// можно замутить встроенный язык с переменными
// При встрече тега HTML создать i = 0
// Пропустить сколько угодно каких угодно тегов
// заматчить много последовательностей <TD> ... </TD>
// При матчинге очередного TD инкрементнуть переменную
// В итоге мы посчитаем число пар <TD>...</TD> заодно.

HTML $i=0, * *, (TD $i++, * *, /TD)*

Не будет ли такое быстрее, чем построение в памяти всего DOM-дерева и исполнение на этом дереве XPath-запросов?



Последнее исправление: igloev (всего исправлений: 4)

Тебе нужно быстро или корректно? Потому что браузер все равно превращается щитимеле в дерево, и именно дерево для него имеет смысл. Вот если дерево обратно экспортировать в XHTML, то уже можно прыгать с регулярками или их подобиями.

byko3y ★★★★
()
Ответ на: комментарий от byko3y

Тебе нужно быстро или корректно? Потому что браузер все равно превращается щитимеле в дерево, и именно дерево для него имеет смысл. Вот если дерево обратно экспортировать в XHTML, то уже можно прыгать с регулярками или их подобиями.

Браузер тут ни при чём вроде.

igloev
() автор топика
Ответ на: комментарий от byko3y

HTML - это язык для браузеров, больше у него нет никаких применений. Что значит «браузер тут не при чем»?

Я могу скачать HTML обратившись по HTTP к серверу, не являясь браузером. С целью выпарсить что-то с сайта. Оторажать страничку не трубуется. И сайт не отдаёт то же самое в другом формате.

igloev
() автор топика

Владимир

То о чем вы говорите - малая часть айсберга.
Погуглите типа «как работает рендеринг в браузере» ..., ...

anonymous
()
Ответ на: комментарий от anonymous

То о чем вы говорите - малая часть айсберга.
Погуглите типа «как работает рендеринг в браузере» ..., ...

Не надо это гуглить, тема не об этом.

igloev
() автор топика

Сделай и продемонстрируй разницу.

Но вообще, пытаться регулярками решить все проблемы попахивает диагнозом.

anonymous
()

Ътмл это чистый адок. Если есть вариант взять xml, берите его. Если нет, то придётся чем-то пожертвовать в любом случае. Будет ли такой подход быстрее? Наверное нет. Зависит от объёмов. Эффективней по памяти? Вполне вероятно.

linuxnewbie
()
Ответ на: комментарий от igloev

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

byko3y ★★★★
()
Ответ на: комментарий от shuck

<тут должна быть картинка про парсинг HTML регулярками>

Речь не про регулярки вообще.

igloev
() автор топика
Ответ на: комментарий от dear_amomynous_v2_1

Я это к тому что предварительный парсинг тегов тебе сильно не поможет с дальнейшим парсингом «регулярками».

Почему не поможет? На выходе будет последовательность объектов

DIV, DIV, /DIV, DIV data-div==«</div foo=bar><div>», DIV

И она не должна «помоч», она необходимый этап, машина регулярок ведь работает на этих объектов.

igloev
() автор топика
Ответ на: комментарий от byko3y

Сайт отдавал браузеру браузерово, и его не волнует, что ты там что-то перехватил своей тулзой.

Мы и не говорим, что его там что-то волнует.

igloev
() автор топика
Ответ на: комментарий от igloev

Хорошо. Повторю тебе то, что сказал первый комментатор - есть парсеры, которые дёргают коллбэк заместо построения дерева. Это подходит под описание твоей задачи.

dear_amomynous_v2_1
()
Ответ на: комментарий от dear_amomynous_v2_1

Если на входе

<div>
  <div class="foo">
    <p>FOO</p>
  </div>
  <div class="bar" data-bar="quux">
    <p><i>BAR</i></p>
  </div>
</div>

Твой колбэк получит по очереди что-то вроде:

<div>
<div><div class="foo">
<div><div class="foo"><p>
<div><div class="foo"><p>FOO
<div><div class="bar" data-bar="quux">
<div><div class="bar" data-bar="quux"><p>
<div><div class="bar" data-bar="quux"><p><i>
<div><div class="bar" data-bar="quux"><p><i>BAR

Но в виде объектов с метаинформацией, вроде порядкового номера доченего объекта.

dear_amomynous_v2_1
()

у тебя там гигабайт html на одной страничке или ты запускаешься на микроконтроллере?

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

Ford_Focus ★★★★★
()
Ответ на: комментарий от anonymous

С подмножеством не путаешь, пед-ант?

anonymous
()

Ты нуб. HTML — не XML, в нём не всегда теги закрыты. Например, <ul> часто не имеет парного </ul>: во-первых, потому что олдскульных вебмакак так учили, во-вторых — браузеры при наличии закрывающего тега ведут себя иначе и добавляют нежелательные отступы, которые приходится убирать дополнительными CSS-костылями. Непарные теги и вовсе поголовно без слеша юзаются, но это хотя бы решается словарём непарных тегов. Альзо, покури готовые парсеры, там уже наверняка есть нечто проще построения DOM.

anonymous
()
Ответ на: комментарий от anonymous

Ты нуб. HTML — не XML, в нём не всегда теги закрыты.

Совершеннейшим образом насрать. Закрытие не требовалось.

igloev
() автор топика

1. Сначала разобрать HTML-документ на линейную последовательность тегов. Тег - имя + набор атрибутов. Иерархии нет. Закрывающий тег - тупо отдельное имя в той же плоской последовательности.

Это называется лексический анализ.

2. Рассмотреть всю эту последовательность как строку символов, где символ - тег.

3. Сделать regexp-машинку, которая оперирует не символами текста, а тегами.

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

Не будет ли такое быстрее, чем построение в памяти всего DOM-дерева и исполнение на этом дереве XPath-запросов?

Результатом работы синтаксического анализатора является синтаксическое дерево, чем, в некотором смысле, и является DOM. Как я понимаю, вопрос можно перформулировать следующим образом: «не будут ли мой клёвый парсер и моё клёвое дерево быстрее, чем те, что я сейчас использую?» Ответ - нет.

Laz ★★★★★
()
Ответ на: комментарий от Laz

Регекспы были полезны на предыдущем этапе, но здесь они безвластны

Неправильно. Речь не про рэгэкспы вообще. Дальше не четал.

igloev
() автор топика
Ответ на: комментарий от Laz

Результатом работы синтаксического анализатора является синтаксическое дерево,

Ну нет, нам не нужен синтаксический анализатор.

igloev
() автор топика
Ответ на: комментарий от igloev

Сделать regexp-машинку
Речь не про рэгэкспы вообще.

Быстрый парсинг HTML
нам не нужен синтаксический анализатор

nuff said.

Laz ★★★★★
()
Ответ на: комментарий от Laz

3. Сделать regexp-машинку, которая оперирует не символами текста, а тегами.

Регекспы были полезны ...

Регекспы были полезны ... когда они были «обыкновенными регулярными выражениями», которые эквивалентны детерминированными конечным автоматам без магазина. Но история ойти пошла другим путем, теперь «регулярными выражениями» называют хер знает что, что даже автомат с магазином не всегда разберет то, что подразумевают под регекспом. И автор темы движется в том же направлении - «сделать regexp-машинку, которая...»

anonymous
()
// заматчить любую пару тегов <TD> + </TD> с любыми тегами между ними.
TD, * *, /TD

Я правильно понимаю, что для «<TD id=1></TD><TD id=2></TD>» этот парсер должен выдать

<TD id=1></TD>
<TD id=1></TD><TD id=2></TD>
<TD id=2></TD>
?

monk ★★★★★
()

Не будет ли такое быстрее, чем построение в памяти всего DOM-дерева и исполнение на этом дереве XPath-запросов?

Если п.1 читает в память, то объём памяти будет сравним с построением DOM. А вот задачу типа «получить строки таблицы, в которых ровно 16 ячеек» на этом regexp-парсере не решить.

monk ★★★★★
()

регекспом тег или не тег определить - уже задача

а еще и на подсчет пар замахнулся...

<div value="<div><div></div>">
  <textarea><div></div></div></textarea>
</div>

Kokonavtuz
()
Ответ на: комментарий от crutch_master

markup language.
extended vs hypertext.
всё валидации по ца согласно описанию DTD.
по html первое всплывает что strict, xhtml.
попробуй валидный html по strict скормить xml валидатору с strict.dtd. есть ненулевая вероятность что и он признает его валидным.

etwrq ★★★★★
()

Именно поэтому на смену лютому здецу под названием HTML пришел XHTML, как компромисс между страшным для машины HTML и страшным для человека XML.
Смысл гипертекстовой разметки как раз и заключается в иерархии.

:) При попытке рассматривать его как линейную (одномерную) последовательность, ты попадаешь на уровень абстракции ниже ожидаемого, где в иерархиях (двумерных сущностях) ещё нет смысла.

blexey ★★★★★
()

Я за бан.

Очередной нудный клоун, не боись скоро каникулы.

Не парь людям мозги, жалкий школолош :-D

Twissel ★★★★★
()
Ответ на: комментарий от Twissel

Владимир

ТС 18.04.19 зарегистрировался /троль не троль время покажет/.
Что касается парсинга страниц, то использую DOM /альтернатива DOM мне не известна/.

anonymous
()
Ответ на: комментарий от anonymous

Комментарии излишни.

От тебя их и не просят, чё.

igloev
() автор топика
Ответ на: комментарий от Twissel

Очередной нудный клоун, не боись скоро каникулы.

Я за бан тебя, пятизвёздочный пустомеля без сообщений по сути в треде.

igloev
() автор топика
Ответ на: комментарий от Kokonavtuz

регекспом тег или не тег определить - уже задача

Что за народ. В треде нет речb про регекспы вообще. Екарны екибастуз, полстраны читает не глазами.

igloev
() автор топика
Ответ на: комментарий от monk

Неправильно. Для указанного он выдаст

TD id=1, /TD, TD id=2, /TD

Всё тупо линейно. Откуда у вас взялись в «выдаче» закрывающие теги - загадка. Парсер не думает ни про какой DOM, а воспринимает входящий HTML как тупую последовательность любых тегов. Про то, что теги могут быть закрытые или нет он вообще не в курсе. Он рад любому тегу в любой момент последовательности. Закрывающий тег - просто другое имя тега для него. Есть тег TD и есть тег /TD, которые никак не связаны никакой логикой с точки зрения разбора.

igloev
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.