Можно ли использовать селекторы jQuery / манипулирование DOM на стороне сервера с помощью Node.js?

Обновление (27 июня 18) . Похоже, что произошло значительное обновление jsdom, из-за которого исходный ответ больше не работает. Я нашел this ответ, который объясняет, как использовать jsdom сейчас. Я скопировал соответствующий код ниже.

var jsdom = require("jsdom");
const { JSDOM } = jsdom;
const { window } = new JSDOM();
const { document } = (new JSDOM('')).window;
global.document = document;

var $ = jQuery = require('jquery')(window);

Примечание: В первоначальном ответе не упоминается, что вам также потребуется установить jsdom с помощью npm install jsdom

Обновление (конец 2013 г.) : официальная команда jQuery наконец-то взяла на себя управление пакетом jquery в npm:

npm install jquery

Затем:

require("jsdom").env("", function (err, window) {
    if (err) {
        console.error(err);
        return;
    }
    var $ = require("jquery")(window);
});

Да, вы можете, используя созданную мной библиотеку, называемую nodeQuery https://github.com/tblobaum/nodeQuery

var Express = require('express')
    , dnode = require('dnode')
    , nQuery = require('nodeQuery')
    , express = Express.createServer();

var app = function ($) {
    $.on('ready', function () {
        // do some stuff to the dom in real-time
        $('body').append('Hello World');
        $('body').append('<input type="text" />');
        $('input').live('click', function () {
            console.log('input clicked');
            // ...
        });
    });
};

nQuery
    .use(app);

express
    .use(nQuery.middleware)
    .use(Express.static(__dirname   '/public'))
    .listen(3000);

dnode(nQuery.middleware).listen(express);

На момент написания этой статьи также существует поддерживаемая Cheerio Глядя на вывод

Быстрая, гибкая и компактная реализация ядра jQuery, разработанная специально для сервера.

массивов jsdom теперь вы можете. Просто посмотрите на их пример jquery в каталоге примеров.

Это моя формула сделать простой сканер в Node.js. Это основная причина желания манипулировать DOM на стороне сервера и, возможно, именно поэтому вы попали сюда.

Во-первых, используйте request Скорость примерно на 1/5, как в первом примере. Свойство cheerio и начинайте манипулирование DOM так же, как и с помощью jQuery.

Рабочий пример:

var
    request = require('request'),
    cheerio = require('cheerio');

function parse(url) {
    request(url, function (error, response, body) {
        var
            $ = cheerio.load(body);

        $('.question-summary .question-hyperlink').each(function () {
            console.info($(this).text());
        });
    })
}

parse('http://stackoverflow.com/');

Этот пример выведет на консоль все основные вопросы, отображаемые на домашней странице SO. Вот почему я люблю Node.js и его сообщество. Это не может быть проще, чем это :-)

Установочные зависимости:

npm install request cheerio

И запустите (при условии, что приведенный выше скрипт находится в файловом crawler.js):

узле crawler.js


Кодировка

Некоторые страницы будут содержать неанглийский контент в определенное кодирование, и вам нужно будет декодировать его в UTF-8. Например, страница на бразильском португальском языке (или любом другом языке латинского происхождения), вероятно, будет закодирована в ISO-8859-1 (он же «latin1»). Когда требуется декодирование, я говорю request не интерпретировать содержимое каким-либо образом, а вместо этого использовать iconv-lite для выполнения работы. { *} Перед запуском установите зависимости:

Рабочий пример:

var
    request = require('request'),
    iconv = require('iconv-lite'),
    cheerio = require('cheerio');

var
    PAGE_ENCODING = 'utf-8'; // change to match page encoding

function parse(url) {
    request({
        url: url,
        encoding: null  // do not interpret content yet
    }, function (error, response, body) {
        var
            $ = cheerio.load(iconv.decode(body, PAGE_ENCODING));

        $('.question-summary .question-hyperlink').each(function () {
            console.info($(this).text());
        });
    })
}

parse('http://stackoverflow.com/');

npm install request iconv-lite cheerio

Следующие ссылки

И, наконец, там есть функция

узле crawler.js


Следующим шагом будет переход по ссылкам. Допустим, вы хотите перечислить все постеры с каждого главного вопроса в SO. Вы сначала нужно перечислить все главные вопросы (пример выше), а затем ввести каждую ссылку, проанализировав страницу каждого вопроса, чтобы получить список вовлеченных пользователей.

может начаться обратный вызов ада

Код отредактированной версии этого кода . Чтобы избежать этого, вы должны использовать какой-то вид обещания, фьючерсы и т. д. Я всегда держу в своем наборе инструментов. Итак, вот полный пример сканера, использующего async: async Перед запуском:

var
    url = require('url'),
    request = require('request'),
    async = require('async'),
    cheerio = require('cheerio');

var
    baseUrl = 'http://stackoverflow.com/';

// Gets a page and returns a callback with a $ object
function getPage(url, parseFn) {
    request({
        url: url
    }, function (error, response, body) {
        parseFn(cheerio.load(body))
    });
}

getPage(baseUrl, function ($) {
    var
        questions;

    // Get list of questions
    questions = $('.question-summary .question-hyperlink').map(function () {
        return {
            title: $(this).text(),
            url: url.resolve(baseUrl, $(this).attr('href'))
        };
    }).get().slice(0, 5); // limit to the top 5 questions

    // For each question
    async.map(questions, function (question, questionDone) {

        getPage(question.url, function ($$) {

            // Get list of users
            question.users = $$('.post-signature .user-details a').map(function () {
                return $$(this).text();
            }).get();

            questionDone(null, question);
        });

    }, function (err, questionsWithPosters) {

        // This function is called by async when all questions have been parsed

        questionsWithPosters.forEach(function (question) {

            // Prints each question along with its user list
            console.info(question.title);
            question.users.forEach(function (user) {
                console.info('t%s', user);
            });
        });
    });
});

npm install request async cheerio

Использованные библиотеки привязать его к переменной

), но, похоже, довольно хороший баланс. Это на

узле crawler.js

Ответ Шона

Is it possible to pause a Docker image build?
    conradk
    Thomasleveil
PHP Image Crop Issue
    Elyor
    Houston Molinar
Add two object in rails
    user1670773
    Makoto
    max
Asymmetric encryption discrepancy - Android vs Java
    Cookie Monster
    Wand Maker
Objective-C: Adding 10 seconds to timer in SpriteKit
    Christian K Rider

И это Основное, что вы должны знать, чтобы начать создавать собственные сканеры :-)


do stuff:

в 2016 году все намного проще. установите jquery в node.js с вашей консоли:

npm install jquery

https://github.com/tmpvar/jsdom $ (например, я к ней привык) в вашем коде node.js:

var $ = require("jquery");

# note ВСЕ LOWERCASE

$.ajax({
    url: 'gimme_json.php',
    dataType: 'json',
    method: 'GET',
    data: { "now" : true }
});

также работает для gulp, поскольку она основана на node.js.

Я считаю, что ответ на этот вопрос теперь да.
модуль jQuery можно установить с помощью:

var navigator = { userAgent: "node-js" };  
var jQuery = require("./node-jquery").jQueryInit(window, navigator);

npm install jquery --save Ссылки на jQuery в Node.js **:

npm install jsdom --save

const jsdom = require("jsdom");
const dom = new jsdom.JSDOM(`<!DOCTYPE html>`);
var $ = require("jquery")(dom.window);


$.getJSON('https://api.github.com/users/nhambayi',function(data) {
  console.log(data);
});

Вы должны получить окно, используя новый JSDOM API.

npm install jquery

Пример:

var $ = require('jquery');
var http = require('http');

var options = {
    host: 'jquery.com',
    port: 80,
    path: '/'
};

var html = '';
http.get(options, function(res) {
res.on('data', function(data) {
    // collect the data chunks to the variable named "html"
    html  = data;
}).on('end', function() {
    // the whole of webpage data has been collected. parsing time!
    var title = $(html).find('title').text();
    console.log(title);
 });
});

Мой рабочий код:

, а затем:

const jsdom = require("jsdom");
const { window } = new jsdom.JSDOM(`...`);
var $ = require("jquery")(window);

или, если окно присутствует, тогда:

npm install jquery

Это решение, как упомянуто

global.jQuery   = require('jquery');
global.$        = global.jQuery;

правильного

typeof window !== "undefined" ? window : this;
window.jQuery   = require('jquery');
window.$        = window.jQuery;

Warning {* } Итак, подведем итог: когда вы делаете

. Это просто быстрое решение, помогающее людям запускать свой настоящий код jQuery с использованием структуры приложения Node, но это не философия Node, поскольку jQuery все еще работает на стороне клиента, а не на стороне сервера. Я извиняюсь за неправильный ответ. Это вернет true для ветви Что касается PHP (или, вообще говоря, веб-сервера в целом), HTML-страница не сложнее, чем большая строка. Вы также можете визуализировать Jade с помощью узла и поместить свой код jQuery внутрь. Вот код jade-файла: Прежде всего установите его


После установки вы можете использовать его, как показано ниже

!!! 5
html(lang="en")
  head
    title Holamundo!
    script(type='text/javascript', src='http://code.jquery.com/jquery-1.9.1.js')
  body
    h1#headTitle Hello, World
    p#content This is an example of Jade.
    script
      $('#headTitle').click(function() {
        $(this).hide();
      });
      $('#content').click(function() {
        $(this).hide();
      });

Полный учебник вы можете посмотреть здесь:

npm install jquery -S

Модуль

import $ from 'jquery';
window.jQuery = window.$ = $;
$(selector).hide();

это отличный инструмент. Но если вы хотите оценить целые страницы и сделать что-нибудь интересное на их стороне сервера, я предлагаю запустить их в их собственном контексте: jQuery.documentSize, предоставляет

Так что такие вещи, как jsdom на сайте, не будут мешать самому процессу Node.

vm.runInContext

Вы можете найти документацию require / CommonJS Начиная с jsdom v10, функция .env () устарела. Я сделал это, как показано ниже, после того, как попробовал много вещей, требующих jquery:

Надеюсь, это поможет вам или всем, кто сталкивался с такими проблемами говорится, что . Ура!

Начиная с jsdom v10, функция .env () устарела. Я сделал это, как показано ниже, после того, как попробовал много вещей, требующих jquery:

var jsdom = require('jsdom');
const { JSDOM } = jsdom;
const { window } = new JSDOM();
const { document } = (new JSDOM('')).window;
global.document = document;

var $ = jQuery = require('jquery')(window);

Надеюсь, это поможет вам или всем, кто сталкивался с такими проблемами

Нет. Это будет довольно большое усилие для переноса среды браузера на узел.

Другой подход, который я сейчас изучаю для модульного тестирования, заключается в создании «пробной» версии jQuery, которая обеспечивает обратные вызовы всякий раз, когда вызывается селектор.

Таким образом, вы можете тестировать свои плагины jQuery, не имея DOM. Вам все равно придется тестировать в реальных браузерах, чтобы увидеть, работает ли ваш код в открытом режиме, но если вы обнаружите специфичные для браузера проблемы, вы также можете легко «насмехаться» над ними в своих модульных тестах.

Я отправлю что-нибудь на github.com/felixge, как только он будет готов к показу.

Вы можете использовать У меня была другая проблема, я не хотел кодировать данные в gzip, но в , он позволяет использовать гибридные browserjs и nodejs.

Раньше я пытался использовать canvas2d в nodejs, но в конце концов сдался. Он не поддерживается по умолчанию для nodejs и слишком сложен для его установки (много-много … зависимостей). Пока я не использую Electron, я могу легко использовать весь свой предыдущий код browserjs, даже WebGL, и передать значение результата (например, result base64 данные изображения) к коду nodejs.

Не то, что я знаю из. DOM — это вещь на стороне клиента (jQuery анализирует не HTML, а DOM).

Вот некоторые текущие проекты Node.js:

http://wiki.github.com/ry/node

А SimonW djangode — чертовски круто …

Альтернативой является использование Underscore.js . Он должен предоставить то, что вы, возможно, хотели на стороне сервера от JQuery.