LINUX.ORG.RU

Ъ-way обработки xhtml/xml на lisp


0

0

Обчитался топиков про cl и захотелось попробовать его в деле.

Задача из жизни.
Есть некий сайт без внешнего API, с которого нужно по расписанию сдирать странички и обрабатывать содержащуюся в них информацию.

На java я бы это делал примерно так: quartz (запуск паука по расписанию) -> httpclient (паук) -> jtidy (приводим к минимальному подобию xhtml) -> xalan (конвертируем в нашу модель) -> jaxb (загружаем из xml в объекты) -> логика.

Как будет выглядеть аналог на common lisp?

>Дата регистрации: 04.08.2009 16:10:26 >javaarchitect (*) (04.08.2009 16:12:35)

Толстовато...

А если по теме: начало примерно так-же: crond (расписание), trivial-http/cl-curl/drakma/smth else (загребание страничек). Дальше уже интереснее, всё зависит от того, что именно нужно из страниц выбирать и как именно обрабатывать.

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

> А если по теме: начало примерно так-же: crond (расписание), trivial-http/cl-curl/drakma/smth else (загребание страничек). Дальше уже интереснее, всё зависит от того, что именно нужно из страниц выбирать и как именно обрабатывать.

Страничка содержит информацию из БД с наложенным оформлением.
Нужно восстановить эту информацию в удобном для дальнейшей обработке виде.

Для примера можно взять эту ветку форума (http://www.linux.org.ru/view-message.jsp?msgid=3932724) и вытащить из неё множество записей вида (msgid,replytomsg, author, date, text).

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

>Для примера можно взять эту ветку форума (http://www.linux.org.ru/view-message.jsp?msgid=3932724) и вытащить из неё множество записей вида (msgid,replytomsg, author, date, text).

Маловато данных) На верхнем уровне всё будет выглядеть как-то так:

(def-html-fields lor-page ()
 (msgid (xpath ...))
 (replyto (xpath ...))
 (author (xpath ...))
 (date (xpath ...))
 (text (xpath ...)))

(def-db-fileds lor-db (:db-name "LorDB")
 (msgid "MsgID")
 (replyto "ReplyTo")
 (author "Author"
 (date "Date")
 (text "Text"))

(collect from "http://www.linux.org.ru/view-message.jsp?msgid=3932724"
         using lor-page
         into lor-db)

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

Как-то так) Это с потолка. Конкретный язык будет зависить от прогнозов на дальнейшее развитие паучка: будут ли дополнятся поля, будет ли изберательная сборка только определённых полей, взаимоотношения полей (дерево, граф, etc), будут ли добавлятся другие сайты и т.п.

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

Sectoid ★★★★★
()
Ответ на: комментарий от guest-3484-2009

> парсер - s-xml

Местный html, как и большинство вокруг, напрямую в парсер не запихнёшь: он не well-formed xml.
Нужна чистка. Как это сделать в cl?

Из очищенного xhtml дополнительно нужно выкинуть всё оформление и прочий JS, оставив только данные.
В моём примере этим занимается xsl. Что будет аналогом в cl?

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

>Внутренности "(collect ..." - как раз самое интересное.

Это достаточно объемный кусок (скорее даже времеемкий). Если на пальцах: это макрос, который берёт соотв. схему источника данных, УРЛ источника, а также назначение, и разворачивается в код подобной струтуры:

[drakma calls] --> [tidy calls (if needed)] --> [xpath calls] --> [cl-sql calls]

Если интересует всё-таки сам код, то, как я и писал выше, можно устроить contest на выходных (в рабочее время не могу -- и так много времени на ЛОРе трачу).

2All: может кто тоже хочет поучавствовать? Интересно было бы поглядеть на такого зверька на Haskell, ML или Erlang.

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

>Местный html, как и большинство вокруг, напрямую в парсер не запихнёшь: он не well-formed xml. Нужна чистка. Как это сделать в cl?

Например этим -- http://tidy.sourceforge.net/ =)

>Из очищенного xhtml дополнительно нужно выкинуть всё оформление и прочий JS, оставив только данные. В моём примере этим занимается xsl. Что будет аналогом в cl?

внешним xsl-преобразователем. Если сильно хочется внутреннего, можно обернуть какой-нить из существующих и имеющих C API, благо CFFI/UFFI есть.

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

> Если интересует всё-таки сам код, то, как я и писал выше, можно устроить contest на выходных (в рабочее время не могу -- и так много времени на ЛОРе трачу).

Можно попробовать устроить.

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

> Смотрю drakma.

Под sbcl/win32 так и не удалось поставить: (asdf-install:install :drakma) вылетает с невнятной ошибкой.
Ладно, попробуем в Linux.

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

>Местный html, как и большинство вокруг, напрямую в парсер не запихнёшь: он не well-formed xml. >Нужна чистка. Как это сделать в cl?

Делал на пистоне -

1) сначала разбивал входной поток на токены (тег, текст, комментарий) - util/html_tokenizer.py

2) потом прогонял токены через стек состояний чтобы отследить контекст появления тега. Принцип такой: дождался определенного тега и вешаешь хук в котором ждешь появления вложенного тега представляющего интерес. Когда уровень вложенности тегов становится ниже того на котором повешен хук, хук снимается и активизируется предыдущий. Чтобы избежать разбалансировки стека состояний из-за непарных html тегов при получении закрывающего тега из стека вынимаются все теги не соответствующие закрывающему тегу. Также там активно юзаются хуки на закрытие тега и на захват текста. util/ctracker.py, util/chtmlparser.py

http://rapidshare.com/files/263656408/src.zip.html

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

работает.
Под виндой не работает asdf-install.
И некоторые проблемы с cl+ssl, с новыми версиями Win32 Openssl, если конкретно. Я, помнится, там руками правил некоторые вещи.

guest-3484-2009
()
Ответ на: комментарий от Absurd

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

Спасибо, интересно.

Скачал исходники, посмотрел pylor/lorthreadfetcher.py.
Разбор получается слишком громоздким (и не совсем Ъ).
Т.е. вместо использования чисто декларативного <xsl:template match="xhtml:div[@class='msg']">, обход дерева приходится делать фактически вручную.

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

Для скачивания страниц подходит drakma[1]. Парсим html используя closure-html[2], а xml - используя closure-xml[3] (он же cxml). Для xslt-преобразования годится xuriella-xslt[4], а для преобразования из xml в объекты - XMLisp[5].

[1] http://weitz.de/drakma/
[2] http://common-lisp.net/project/closure/closure-html/
[3] http://common-lisp.net/project/cxml/
[4] http://common-lisp.net/project/xuriella/
[5] http://www.agentsheets.com/lisp/XMLisp/

dmitry_vk ★★★
()

cl-libxml2 - моя обёртка над libxml2/libxslt, в том числе поддерживает интерфейс для невалидирующего html-парсера, а также xpath, может скачать, распарсить и далее что захочешь, в том числе и xslt.

http://quotenil.com/git/?p=clon.git;a=summary - планировщик, позволяёт вызывать функцию по расписанию.

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

>Разбор получается слишком громоздким (и не совсем Ъ).

HTML до неприличия нестрогий. Даже годную для практической работы граматику на ANTLR написать крайне проблематичено из-за того что теги типа <p> разрешили делать непарными из-за чего граматика трещит по швам. Поэтому я не нашел для себя другого выхода кроме как работать с html ручками.

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