Применение DOM-манипуляций к HTML и сохранение результата? - PullRequest
6 голосов
/ 29 июля 2011

У меня есть около 100 статических HTML-страниц, к которым я хочу применить некоторые манипуляции с DOM.Все они следуют одной и той же структуре HTML.Я хочу применить некоторые манипуляции с DOM к каждому из этих файлов, а затем сохранить полученный HTML.

Вот манипуляции, которые я хочу применить:

# [start]
$("h1.title, h2.description", this).wrap("<hgroup>");
if ( $("h1.title").height() < 200 ) {
  $("div.content").addClass('tall');
}
# [end]
# SAVE NEW HTML

Первая строка (.wrap()) Я мог бы легко сделать поиск и замену, но это становится сложно, когда я должен определить вычисленную высоту элемента, которая не может быть легко определена без JavaScript.

Кто-нибудь знает, как мне этого добиться?Спасибо!

Ответы [ 3 ]

8 голосов
/ 29 июля 2011

Хотя первая часть действительно может быть решена в «текстовом режиме» с использованием регулярных выражений или более полной реализации DOM в JavaScript, для второй части (вычисление высоты) вам понадобится настоящий полноценный браузер или система без головы двигатель вроде PhantomJS .

С домашней страницы PhantomJS :

PhantomJS - это инструмент командной строки, который упаковывает и встраивает WebKit. Буквально он действует как любой другой веб-браузер на основе WebKit, за исключением того, что ничего не отображается на экране (таким образом, термин безголовый). В В дополнение к этому, PhantomJS можно контролировать или создавать сценарии, используя его JavaScript API.


Ниже приведена схематическая инструкция (которая, как я признаю, не тестировалась).

В вашем скрипте модификации (скажем, modify-html-file.js) откройте страницу HTML, измените ее дерево DOM и console.log HTML-код корневого элемента:

var page = new WebPage();

page.open(encodeURI('file://' + phantom.args[0]), function (status) {
    if (status === 'success') {
        var html = page.evaluate(function () {
            // your DOM manipulation here
            return document.documentElement.outerHTML;
        });
        console.log(html);
    }
    phantom.exit();
});

Затем сохраните новый HTML, перенаправив вывод вашего скрипта в файл:

#!/bin/bash

mkdir modified
for i in *.html; do
    phantomjs modify-html-file.js "$1" > modified/"$1"
done
4 голосов
/ 27 августа 2015

Я пытался PhantomJS , как в ответе katspaugh , но столкнулся с несколькими проблемами, пытаясь манипулировать страницами.Мой вариант использования заключался в изменении статического HTML-вывода Doxygen без изменения самого Doxygen.Цель состояла в том, чтобы уменьшить размер файла, удалив ненужные элементы со страницы, и преобразовать его в HTML5.Кроме того, я также хотел использовать jQuery для более легкого доступа к элементам и их изменения.

Загрузка страницы в PhantomJS

Похоже, что API сильно изменились со времени принятия ответа.Кроме того, я использовал другой подход (полученный из этого ответа ), который будет важен для смягчения одной из основных проблем, с которыми я столкнулся.

var system = require('system');
var fs = require('fs');
var page = require('webpage').create();

// Reading the page's content into your "webpage"
// This automatically refreshes the page
page.content = fs.read(system.args[1]);

// Make all your changes here

fs.write(system.args[2], page.content, 'w');
phantom.exit();

Предотвращение запуска JavaScript

Моя страница использует Google Analytics в нижнем колонтитуле, и теперь страница изменена вне моего намерения, предположительно потому, что был запущен JavaScript.Если мы отключим javascript, мы не сможем на самом деле использовать jQuery для изменения страницы, так что это не вариант.Я попытался временно изменить тег, но когда я это сделаю, каждый специальный символ заменяется на экранированный html-эквивалент, уничтожая весь код JavaScript на странице.Затем я наткнулся на этот ответ , который дал мне следующую идею:

var rawPageString = fs.read(system.args[1]);
rawPageString = rawPageString.replace(/<script type="text\/javascript"/g, "<script type='foo/bar'");
rawPageString = rawPageString.replace(/<script>/g, "<script type='foo/bar'>");

page.content = rawPageString;

// Make all your changes here

rawPageString = page.content;
rawPageString = rawPageString.replace(/<script type='foo\/bar'/g, "<script");

Добавление jQuery

На самом деле пример о том, какиспользовать JQuery.Тем не менее, я думал, что автономная копия будет более подходящей.Сначала я попытался использовать page.includeJs, как в примере, но обнаружил, что page.injectJs больше подходит для варианта использования.В отличие от includeJs, в контекст страницы не добавлен тег <script>, и выполнение вызова блокирует, что упрощает код.jQuery был помещен в ту же директорию, из которой я выполнял свой скрипт.

page.injectJs("jquery-2.1.4.min.js");
page.evaluate(function () {

  // Make all changes here

  // Remove the foo/bar type more easily here
  $("script[type^=foo]").removeAttr("type");
});

fs.write(system.args[2], page.content, 'w');
phantom.exit();

Собираем все вместе

var system = require('system');
var fs = require('fs');
var page = require('webpage').create();

var rawPageString = fs.read(system.args[1]);
// Prevent in-page javascript execution
rawPageString = rawPageString.replace(/<script type="text\/javascript"/g, "<script type='foo/bar'");
rawPageString = rawPageString.replace(/<script>/g, "<script type='foo/bar'>");

page.content = rawPageString;

page.injectJs("jquery-2.1.4.min.js");
page.evaluate(function () {

  // Make all changes here

  // Remove the foo/bar type
  $("script[type^=foo]").removeAttr("type");
});

fs.write(system.args[2], page.content, 'w');
phantom.exit();

Используя его из командной строки:

phantomjs modify-html-file.js "input_file.html" "output_file.html"

Примечание: это было проверено и работало с PhantomJS 2.0.0 в Windows 8.1.

Совет Pro: Если скорость имеет значение, вам следует рассмотреть возможность итерации файлов внутри скрипта PhantomJS, а нескрипт оболочки.Это позволит избежать задержки, которую имеет PhantomJS при запуске.

1 голос
/ 29 июля 2011

вы можете получить ваш измененный контент $ ('html'). Html () (или более конкретным селектором, если вам не нужны такие вещи, как теги head), затем отправьте его в виде большой строки на ваш сервер и напишите сторона файлового сервера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...