gpt4 book ai didi

javascript - 使用 PhantomJS 的 jQuery 错误

转载 作者:行者123 更新时间:2023-12-03 06:34:49 28 4
gpt4 key购买 nike

我目前正在开发一个自动化测试脚本,该脚本需要 headless 浏览器(PhantomJS)以及所有可能的 DOM 导航和操作(下载除外)。所以 PhantomJS 应该适合。

但是我无法将 PhantomJS 与 javascript jQuery 一起使用,因为出现以下错误:

var page = require('webpage').create();
page.open('http://mywebsite.com/', function() {
function dothat() {
console.log('0 started');
$('#id').children().eq(0).click();
console.log('0 finished');
return main(1, 0);
}
}
dothat()

此处脚本停止“0 开始”。我加载的页面使用 jQuery,所以我不需要将其下载回来。即便如此,我们还是尝试加载它。

var page = require('webpage').create();
page.open('http://mywebsite.com/', function() {
page.injectJs('jquery-2.2.1.min.js');
function dothat() {
console.log('0 started');
$('#id').children().eq(0).click();
console.log('0 finished');
return main(1, 0);
}
}
dothat()

是的,我在本地同一目录中有该文件...它显示了该错误(非常快):

TypeError: undefined is not a constructor (evaluating 'jQuery.easing[jQuery.easing.def](t,e,n,i,a)')

您建议采取什么措施来解决这个问题?这是 PhantomJS 的内部错误吗?所以我应该在 Ubuntu 上尝试 Firefox 和 Xvfb,还是我在某个地方出错了?我首先将代码更改为完全非 jQuery 版本,但我需要带有类的出色选择器并单击某些对象...

非常感谢您为我指出解决方案!

编辑1:我根据我从第一个答案中了解到的内容对此进行了更改。现在控制台不打印任何内容

var page = require('webpage').create();
page.onConsoleMessage = function(msg, lineNum, sourceId) {
console.log('CONSOLE: ' + msg + ' (from line #' + lineNum + ' in "' + sourceId + '")');
};
page.open('http://mywebsite.com/', function() {
page.injectJs('jquery-2.2.1.min.js');
var result = page.evaluate(function() {
function dothat() {
console.log('0 started');
$('#id').children().eq(0).click();
console.log('0 finished');
return main(1, 0);
}
function main(x, y) {
if (x === 0) {
return setTimeout(dothat(), y);
} else if (x === 1) {
return setTimeout(dothis(), y);
}
}
return main(0, 5000); //first launch
}
});

我不确定这就是你所指出的。

编辑 2:这是一个真实的脚本,想要进入 google.com 并以我的身份登录。但是该脚本无法按预期工作,请参见下文。

var page = require('webpage').create();
page.onConsoleMessage = function(msg) {
console.log('CONSOLE: ' + msg);
};
page.open('https://google.com/', function() {
page.injectJs('jquery-2.2.1.min.js');
page.evaluate(function() {
function dofirst() {
$('#gb_70').click();
return main(1, 0);
}
function dosecond() {
document.getElementById('Email').value = 'myemail@gmail.com';
$('#next').click();
return main(2, 0);
}
function dothird() {
document.getElementById('Passwd').value = 'mypwd';
$('#signIn').click();
}
function main(i, j) {
if (i === 0) {
console.log('launching 0');
return setTimeout(dofirst(), j); // connections
}
else if (i === 1) {
console.log('launching 1');
return setTimeout(dosecond(), 5000);
}
else if (i === 2) {
console.log('launching 2');
return setTimeout(dothird(), 5000);
}
}
return main(0, 5000);
});
});

如您所见,main 是我用来延迟步骤的函数。但是,代码不起作用并返回给我这个错误(或那些错误):

TypeError: null is not an object (evaluating 'document.getElementById('Email').value = 'myemail@gmail.com'')

undefined:7 in dosecond
:22 in main
:4 in dofirst
:18 in main
:29
:30

感谢您一直以来对我的帮助!

最佳答案

在 PhantomJS 中,总是有两个 javascirpt 上下文,其中存在函数和变量:

  1. PhantomJS 上下文
  2. 打开的页面上下文

它们彼此不认识,也不相交!

PhantomJS 无法访问任何目标页面对象或 DOM,这就是为什么 $('#id').children().eq(0).click(); 不起作用- PhantomJS 脚本中没有 jQuery,也没有 DOM 元素。它们处于第二个上下文中,或者换句话说,沙箱中。

要对页面执行任何操作,您必须在那里传送代码。这是在 page.evaluate() 的帮助下完成的方法。

var page = require('webpage').create();
page.open('http://mywebsite.com/', function() {
page.injectJs('jquery-2.2.1.min.js');
var result = page.evaluate(function(){

// You can certainly use functions
// Be sure to declare them also
// inside of page.evaluate
function dothat() {
console.log('0 started');
$('#id').children().eq(0).click();
console.log('0 finished');
return main(1, 0);
}

// Important: don't forget to return result
// back to PhantomJS main context
return dothat();
});
});

请注意,要从沙盒页面上下文接收控制台消息,您必须通过 page.onConsoleMessage 订阅它们回调:

page.onConsoleMessage = function(msg, lineNum, sourceId) {
console.log('CONSOLE: ' + msg + ' (from line #' + lineNum + ' in "' + sourceId + '")');
};

编辑 1 后:糟糕的是,我在编辑示例时丢失了一个括号(已在上面修复),这导致了语法错误,事实上 PhantomJS v2.x 不会提示,它只会默默地卡在那里。这就是您误以为没有控制台消息的原因。首先在 v1.9.8 中或在某些带有语法突出显示的 IDE 中测试脚本是否存在语法错误可能很有用。

您当前的代码应如下所示(缺少的括号也已修复):

var page = require('webpage').create();
page.onConsoleMessage = function(msg, lineNum, sourceId) {
console.log('CONSOLE: ' + msg + ' (from line #' + lineNum + ' in "' + sourceId + '")');
};
page.open('http://mywebsite.com/', function() {
page.injectJs('jquery-2.2.1.min.js');
var result = page.evaluate(function() {
function dothat() {
console.log('0 started');
$('#id').children().eq(0).click();
console.log('0 finished');
return main(1, 0);
}
function main(x, y) {
if (x === 0) {
return setTimeout(dothat(), y);
} else if (x === 1) {
return setTimeout(dothis(), y);
}
}
return main(0, 5000); //first launch
}); //
});

注意:会提示 dothis() 函数不存在。

关于javascript - 使用 PhantomJS 的 jQuery 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38274815/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com