Можно ли использовать селектор jQuery/DOM на стороне сервера с помощью Node.js?
Обновление (27 июня 18). Похоже, что в jsdom
произошло серьезное обновление, из-за которого оригинальный ответ больше не работает. Я нашел этот ответ, который объясняет, как использовать 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
, чтобы загрузить страницу, подлежащую анализу. Когда загрузка будет завершена, обработайте ее 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 запрос на установку cheerio
И запустите (если script выше в файле crawler.js
):
node crawler.js
Некоторые страницы будут иметь не-английский контент в определенной кодировке, и вам нужно будет декодировать его до UTF-8
. Например, страница на бразильском португальском языке (или любой другой язык латинского происхождения), скорее всего, будет закодирована в ISO-8859-1
(a.k.a. "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 запрос на установку iconv-lite cheerio
И наконец:
node crawler.js
Следующим шагом будет следовать ссылкам. Скажем, вы хотите перечислить все плакаты с каждого верхнего вопроса на SO. Вы должны сначала перечислить все главные вопросы (пример выше), а затем ввести каждую ссылку, разобрав каждую страницу вопросов, чтобы получить список вовлеченных пользователей.
Когда вы начнете следовать ссылкам, начнется callback hell. Чтобы этого избежать, вы должны использовать какой-то promises, фьючерс или что-то еще. Я всегда держу 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 запрос на установку async cheerio
Запустите тест:
node 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
И что основное, что вы должны знать, чтобы начать создавать собственные сканеры: -)
в 2016 году все проще. установите jquery на node.js с помощью консоли:
npm install jquery
привяжите его к переменной $
(например, я привык к ней) в вашем node.js-коде:
var $ = require("jquery");
сделай материал:
$.ajax({
url: 'gimme_json.php',
dataType: 'json',
method: 'GET',
data: { "now" : true }
});
также работает для gulp, поскольку он основан на node.js.
var $ = require("jquery"); $.ajax // undefined
(на данный момент не var $ = require("jquery"); $.ajax // undefined
).
npm install jquery
?
Я считаю, что ответ на этот вопрос теперь да. https://github.com/tmpvar/jsdom
var navigator = { userAgent: "node-js" };
var jQuery = require("./node-jquery").jQueryInit(window, navigator);
npm install jquery --save
#note ВСЕ LOWERCASE
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);
});
Модуль jQuery можно установить с помощью:
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);
});
});
Ссылки jQuery в Node.js **:
Вы должны получить окно, используя новый API JSDOM.
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;
Внимание
Это решение, упомянутое Голо Роденом, неверно. Это просто быстрое решение, чтобы помочь людям иметь свой фактический код jQuery, работающий с использованием структуры приложения Node, но это не философия Node, потому что jQuery все еще работает на стороне клиента, а не на стороне сервера. Прошу прощения за неправильный ответ.
Вы также можете отобразить Jade с помощью Node и поместить код jQuery внутри. Вот код нефритового файла:
!!! 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();
});
Начиная с 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);
Надеюсь, что это поможет вам или всем, кто сталкивался с такими проблемами.
Модуль jsdom - отличный инструмент. Но если вы хотите оценить целые страницы и сделать некоторые напуганные вещи на стороне сервера, я предлагаю запустить их в своем собственном контексте:
vm.runInContext
Таким образом, такие вещи, как require
/CommonJS
на сайте, не будут удалять ваш процесс Node.
Здесь вы можете найти документацию здесь. Ура!
Прежде всего установите его
npm install jquery -S
После установки вы можете использовать его, как показано ниже
import $ from 'jquery';
window.jQuery = window.$ = $;
$(selector).hide();
Вы можете проверить полный учебник здесь: https://medium.com/fbdevclagos/how-to-use-jquery-on-node-df731bd6abc7
Вы можете использовать Electron, он позволяет использовать гибридные браузеры и узлы.
Раньше я пытался использовать canvas2d в nodejs, но, в конце концов, я сдался. Он не поддерживается nodejs по умолчанию, и слишком сложно его установить (многие многие... dependeces). Пока я не пользуюсь Electron, я могу легко использовать весь мой предыдущий код browserjs, даже WebGL, и передать значение результата (например, данные результата base64) в код nodejs.
Нет. Для переноса среды браузера на node потребуется большое усилие.
Другим подходом, который я сейчас изучаю для модульного тестирования, является создание "Mock" версии jQuery, которая обеспечивает обратные вызовы всякий раз, когда вызывается селектор.
Таким образом вы могли бы unit test ваши плагины jQuery, не имея фактически DOM. Вам все равно придется протестировать в реальных браузерах, чтобы увидеть, работает ли ваш код в дикой природе, но если вы обнаружите специфические проблемы браузера, вы можете легко "высмеять" те, что и в ваших модульных тестах.
Я вытащу что-то в github.com/felixge, когда он будет готов показать.
Не то, чтобы я знал. DOM - это клиентская сторона (jQuery не анализирует HTML, а DOM).
Вот несколько текущих проектов Node.js:
http://wiki.github.com/ry/node
И SimonW djangode довольно чертовски круто...
Альтернативой является использование Underscore.js. Он должен предоставить то, что вам может потребоваться на стороне сервера из JQuery.