如何将javascript应用于模拟浏览器的html

我已经在互联网上search了如何“创build”一个简单的无头浏览器,因为我有兴趣知道浏览器如何在内部工作。 我想实现一个简单的无头浏览器。

我的意思是:假设你有一个htmlstring和一个javascriptstring,都是作为HttpRequest到服务器的结果; 我怎么能应用JavaScript的HTMLstring?

例如:我向一个X服务器请求了html源文件,并在响应中获得了这个:

<html> <head> <script type="text/javascript" src="javascript.js"> </head> <body> <p id="content"></p> <body> </html> 

然后,我请求javascript.js文件,我得到这个:

 document.getElementById("content").text = "Hello"; 

如何将javascript.js文件的内容应用到html文件中? 我应该遵循的步骤是类似于这样的吗?

  1. parsingHTML源到Javascript的DOM元素
  2. 将JavaScript应用于DOM

我想用Java,Scala或Node.js来做。 Idk如果你明白主要想法…我是拉丁美洲人,而且我的英语不太好。 对不起。 如果不理解,请在评论中告诉我,我将编辑我的post。

编辑:我想要做的,换句话说,就像这样的伪方法/函数(伪代码):

 function applu(html, js){ // Apply js into html } 

如果你正在寻找一个无头的浏览器,我相信你知道phantomsJS 。 PhantomJS是基于苹果webkit浏览器引擎的无头浏览器。

你在这里要求很多 你需要:

  1. 一个javascript运行时(如v8)来运行javascript。
  2. 一个networking引擎,将HTML和它定义的文档对象模型带到现实生活中。

这两件事都需要数百万行代码才能执行。

我的build议是将您的程序与PhantomJS集成。 PhantomJS是一个无头网页浏览器和一个JavaScript环境。 如果您正在使用scala,请启动phantomjs的subprocess并通过std i / o将消息发送给它。 PhantomJS的JS部分意味着你通过它的JavaScript API来使用它,所以你还必须编写一个js脚本来处理来自std i / o的消息。 它没有logging,但是phantomjs有一个system.std.insystem.std.out apis来处理这些消息。

这是很多工作和JVM之外的大量额外资源来实现它的工作。 我看到你正在使用scala,所以你可以用一个简单的解决scheme使用jsoupparsing和修改HTML文档,但是你将不得不使用scala(或java)来完成转换。

其实,现在我想到了,你应该使用与nodejs配对的jsdom。 JSDom实现了dom API,而实际上并不需要渲染它。 jsdom是为无头的nodejs制作的。 如果你想同时使用scala和节点,你也可以使用节点的std I / O,并让它从JVM发送消息。


下面是使用jsdom评估javascript并修改html的一个概念certificate。 这是一个非常简单的解决scheme,对于给定的任务而言,这是最有效的资源(这是一项艰巨的任务)。

我用一个非常简单的概念certificate为你做了一件事 。 要运行的要点做到:

 git clone https://gist.github.com/c8aef41ee27e5304e94f6a255b048f87.git apply-js-to-html cd apply-js-to-html npm install node example.js 

这是榜样的肉:

 const jsdom = require('jsdom'); module.exports = function (html, js) { return new Promise((resolve, reject) => { jsdom.env(html, (error, window) => { if (error) { reject(error); } try { (function evalInContext () { 'use strict'; const document = this.document; const window = this.window; eval(js); resolve(window.document.documentElement.innerHTML); }).call(window); } catch (e) { reject(e); } }); }); } 

这里是使用的模块

 const applu = require('./index'); const html = ` <html> <head></head> <body> <p id="content"></p> <body> </html> `; const js = `document.getElementById("content").innerHTML = "Hello";` applu(html, js).then(result => { console.log('input html: ', html); console.log('output html: ', result); }).catch(err => console.error(error)); 

这里是代码的输出:

 input html: <html> <head></head> <body> <p id="content"></p> <body> </html> output html: <head></head> <body> <p id="content">Hello</p> </body> 

jsdom创build一个无头的windowdocument环境,不呈现任何东西。 您可以使用eval并使用window作为this值在上下文中调用它 。 我也宣布过documentwindow ,将会被撤销的js会在范围内有这些variables。

这只是一个基本的POC,你会自己解决细节问题。