Статьи

Преобразование HTML с помощью Node.js и jQuery


Модуль npm
jsdom позволяет вам использовать jQuery для изучения и преобразования HTML в Node.js. Этот пост объясняет как.

Основы

Как инструмент для обработки HTML, Node.js предлагает важную основу: он может загружать или выгружать данные, а также может читать или записывать на диски
[1] . Чего не хватает, так это возможности разбирать и преобразовывать HTML. К счастью, фреймворк jQuery идеально подходит для этой задачи. Модуль jsdom реализует HTML DOM поверх Node.js, который является всем, что нужно jQuery для запуска на этой платформе. Чтобы установить его, используйте менеджер пакетов узла:

npm install jsdom

JSDOM очень прост в использовании:

var htmlSource = fs.readFileSync("dummy.html", "utf8");
    call_jsdom(htmlSource, function (window) {
    var $ = window.$;

    var title = $("title").text();
    $("h1").text(title);

    console.log(documentToSource(window.document));
});

Выше мы сначала читаем источник html с диска в строку, а затем вызываем jsdom с этим источником. Он вызывает нас обратно, когда все закончено, с оконным объектом. Функция call_jsdom гарантирует, что jQuery уже загружен «в» это окно, поэтому нам нужен только доступ к window. $ И работа с jQuery, как в браузере: документ еще не имеет заголовка, поэтому мы читаем заголовок и положить его в пустой тег h1. Наконец, мы записываем преобразованный HTML в консоль. Вы можете скачать проект
jsdom_demo, чтобы опробовать его; Запустите transform.js на оболочке, напрямую или через Node.js. Ввод:

<!doctype html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>My document</title>
    </head>
    <body>
        <h1></h1>
    </body>
</html>

Выход:

<!doctype html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>My document</title>
    </head>
    <body>
        <h1>My document</h1>
    </body>
<script src="jquery-1.7.1.min.js"></script></html>

Предостережения

Сохранение структуры исходного кода. Исходный исходный код будет изменен несколькими способами: будут добавлены закрывающие теги (например, чтобы закрыть тег <p>), а загрузка jQuery приведет к добавлению тега сценария (см. Вывод выше). Возможный обходной путь для преобразования HTML (в отличие от извлечения данных) — не работать с полным документом. Вместо этого можно использовать $ () для работы с фрагментом HTML, отдельным от документа:

var fragment = $("<ul><li>item</li></ul>");

Видя брошенные исключения. JSDOM ловит все исключения. К сожалению, эта ловля распространяется на обратные вызовы. Например, следующее — это функция, которую мы вызывали ранее.

function call_jsdom(source, callback) {
    jsdom.env(
        source,
        [ 'jquery-1.7.1.min.js' ],  // (*)
        function(errors, window) {  // (**)
            process.nextTick(
                function () {
                    if (errors) {
                        throw new Error("There were errors: "+errors);
                    }
                    callback(window);
                }
            );
        }
    );
}

jsdom проглатывает все исключения, выданные внутри функции обратного вызова в (**), в том числе в любых вызываемых им функциях. Чтобы избежать этого эффекта, вы можете использовать
process.nextTick (), чтобы добавить функцию в очередь цикла событий. Он будет выполнен после завершения текущего кода.

Loading jQuery from a file. The examples in the jsdom readme load jQuery from a URL, causing internet traffic each time the code is run. A solution is to put a copy of jQuery next to the script and specify a file path instead of a URL, as seen above at (*).

Using jQuery multiple times. Do you have to invoke call_jsdom (or jsdom.env) every time you want to use jQuery? No, you can store window somewhere and use it again later. The initial startup is only callback-based to accommodate asynchronous script loading.

Conclusion: What is this good for?

Когда вы сталкиваетесь с необходимостью разбора или преобразования HTML, вы понимаете, насколько велик язык преобразования jQuery. Тем более, что его документация очень хорошо сделана, идеально подходит для обычных пользователей. Описанное выше решение идеально подходит для извлечения информации из HTML. Изменение существующего HTML требует большей осторожности.

Источник: http://www.2ality.com/2012/02/jsdom.html