对HTML应用DOM操作并保存结果

Applying DOM Manipulations to HTML and saving the result?

本文关键字:保存 结果 操作 DOM HTML 应用      更新时间:2023-09-26

我有大约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中不容易确定。

有人知道我怎么才能做到这一点吗?谢谢!

虽然第一部分确实可以使用正则表达式或JavaScript中更完整的DOM实现在"文本模式"下解决,但对于第二部分(高度计算),您将需要一个真正的,完整的浏览器或像PhantomJS这样的无头引擎。

From PhantomJS主页:

PhantomJS是一个打包和嵌入WebKit的命令行工具。从字面上看,它的行为就像任何其他基于webkit的web浏览器,除了这一点没有任何东西显示在屏幕上(因此,术语headless)。在除此之外,还可以使用其控件控制或编写PhantomJSJavaScript 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

我在katspaugh的回答中尝试了PhantomJS,但是在试图操纵页面时遇到了几个问题。我的用例是修改氧的静态html输出,而不修改氧本身。其目标是通过从页面中删除不必要的元素,并将其转换为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运行

我的页面在页脚使用谷歌分析,现在页面被修改超出了我的意图,大概是因为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 h1> 际上有一个关于如何使用jQuery的例子。但是,我认为离线版本会更合适。最初我尝试使用page。如示例中的includeJs,但找到了该页面。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"

注意:这是在Windows 8.1上与PhantomJS 2.0.0一起测试和工作的

专业提示:如果速度很重要,您应该考虑从PhantomJS脚本而不是shell脚本中迭代文件。这将避免PhantomJS在启动时的延迟

你可以通过$('html').html()(或者一个更具体的选择器,如果你不想要的东西,如头部标签)得到你修改的内容,然后提交它作为一个大字符串到你的服务器,并写文件服务器端