Dom PhantomJS在评估之前更改网页内容

Dom PhantomJS在评估之前更改网页内容,dom,phantomjs,Dom,Phantomjs,我想删除HTML元素,或者在评估/呈现网页之前删除网页的前N个字符 有什么方法可以做到这一点吗?这取决于多种情况。我将仅概述以下问题答案的每个组合的步骤 这段JS是称为onload(ol)还是立即计算脚本块(ie) 它是内联脚本(Is)还是单独加载的脚本(src属性)(ls) 脚本块是否也包含一些不应删除的代码(nr),或者是否可以完全删除(rc) 1.脚本单独加载(ls)&代码可以完全删除(rc) 根据匹配的url,注册到onResourceRequested侦听器和request.abort

我想删除HTML元素,或者在评估/呈现网页之前删除网页的前N个字符


有什么方法可以做到这一点吗?

这取决于多种情况。我将仅概述以下问题答案的每个组合的步骤

  • 这段JS是称为onload(ol)还是立即计算脚本块(ie
  • 它是内联脚本(Is)还是单独加载的脚本(src属性)(ls
  • 脚本块是否也包含一些不应删除的代码(nr),或者是否可以完全删除(rc
  • 1.脚本单独加载(ls)&代码可以完全删除(rc) 根据匹配的url,注册到
    onResourceRequested
    侦听器和
    request.abort()

    2.脚本单独加载(ls)并包含其他代码(nr) 只有当以下代码块不依赖于不应删除的代码时(不太可能),才能执行此操作。对于在DOM中注册的单击事件,这很可能是必需的

    在本例中,取消请求(如1.),通过XHR下载脚本,删除不需要的代码部分并将代码块添加到DOM中。要使其正常工作,您需要禁用web安全性,否则,如果资源不在同一域中,则无法请求任何资源:
    --web security=false

    3.脚本加载了DOM(is)和JS,通过
    onload
    (ol)执行,并且可以完全删除(rc) 这可能非常容易出错。您可以从回调中以
    setInterval(function(){},5)
    开始一个间隔。在时间间隔内,您需要检查页面上下文中是否设置了
    window.onload
    (或其他您可以使用的内容)。如果确实是要删除的函数,则可以通过选中
    window.onload.toString().match(/something/)
    来删除它

    这可以在页面上下文(在
    page.evaluate
    )中直接完成

    4.脚本加载了DOM(is)和JS,这些DOM(is)和JS通过
    onload
    (ol)执行,并且还包含其他代码(nr) 像在3中那样开始。,但是您可以执行以下操作,而不是删除
    窗口。onload

    eval("window.onload = " + window.onload.toString().replace(/something/,''))
    
    5.脚本加载DOM(is)&脚本块立即计算(ie) 您可以将页面作为XHR加载,替换文本并将调整后的内容应用于页面。这本质上是一个填充的
    about:blank
    页面。要使其正常工作,您需要禁用web安全性,因为如果资源不在同一个域上,则无法请求任何资源:
    --web security=false
    --local to remote url access=true
    。这也适用于3.4.

    不过,还有一个问题。页面大部分时间不使用完整的URL。因此,当脚本或元素引用
    stuff.php
    PhantomJS时,PhantomJS无法请求它。设置
    page.content
    时,页面URL基本上是关于:空白,所有URL不完整的请求都指向
    file:///...
    。显然没有这样的文件。这些资源必须替换为完整的URL对应项。
    此类URL有三种类型:

    • //example.com/resource.php
      变量协议
    • /resource.php
      变量协议和域
    • resource.php
      变量协议、域和资源路径
    完整示例:

    var page = require('webpage').create(),
        url = 'http://www.example.com';
    
    page.open(url, function(status) {
        if (status !== 'success') {
            console.log('Unable to access network');
        } else {
            var content = page.evaluate(function(url){
                var xhr = new XMLHttpRequest();
                xhr.open("GET", url, false);
                xhr.send();
                return xhr.responseText;
            }, url);
            page.render("test_example.png");
            page.content = content.replace(/xample/g,"asy");
            page.render("test_easy.png");
            console.log("url "+page.url); // about:blank
            phantom.exit();
        }
    });
    

    除了简单的字符串替换之外,您可能还需要研究适当的操作技术。

    出于好奇,是什么阻止了您按原样处理页面?页面希望从iframe调用,因此我需要删除这段JS。回答很好,谢谢。这是一个位于标题中的内联脚本,因此很遗憾,它是选项5。你说的“特定于脚本的东西”是什么意思?如果(top==self){document.location.href=“”;}确定,则代码为5。即使没有特定于脚本的知识也可以。我会尽快编辑。非常原创的解决方案。当您运行代码时,是否出现了“ReferenceError:找不到变量:jQuery”错误?我还尝试了page.injectJs('jquery.min.js');并将该文件放在脚本文件夹中,但也没有任何帮助。如果在页面上下文中使用jQuery,则需要首先删除它。该代码段只是运行在example.com上的一个示例脚本。先看看它在不修改的情况下能做些什么,然后再根据您的案例进行修改。+1谢谢您的回答。还有一点可能是显而易见的:对于5.,如果它不是在线关键的,那么xhr部分和web安全性可以通过
    var repl_content=page.content.replace(“say”,“asy”)然后打印/显示/呈现
    repl_内容