casperjs/slimerjs 在 getElementByXPath 中有效的 waitForSelector 中的选择器无效?
casperjs/slimerjs invalid selector in waitForSelector, which works in getElementByXPath?
我有这个 HTML 文件,test_xpath.htm
:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
<h1>Hello World!</h1>
<div>
<a href="http://whosebug.com">Click me!</a>
</div>
</body>
</html>
在这个文件的文件夹中,我 运行 PHP CLI > 5.4 作为服务器是这样的:
php -S localhost:8080
...因此 HTML 页面可在 http://localhost:8080/test_xpath.htm
.
然后我 运行 这个 SlimerJS 代码:
// run with:
// SLIMERJSLAUNCHER=/usr/bin/firefox46 /home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules/casperjs/bin/casperjs --engine=slimerjs test_xpath.js
var casper = require('casper').create({
verbose: true,
logLevel: 'debug',
userAgent: 'Mozilla/5.0 (X11; Linux i686; rv:43.0) Gecko/20100101 Firefox/43.0',
viewportSize: {width: 1024, height: 768},
pageSettings: {
loadImages: false,//The script is much faster when this field is set to false
loadPlugins: false,
}
});
casper.on("url.changed", function(){
this.then(function(){
this.echo("URL changed " + this.getCurrentUrl()); //getTitle());
});
});
casper.on('remote.message', function(message) {
this.echo('remote message caught: ' + message);
});
casper.start().thenOpen("http://localhost:8080/test_xpath.htm", function() {
console.log("website opened");
});
// set this to true to run - causes "[error] [remote] findAll(): invalid selector provided "//*[text()="Click me!"]":SyntaxError: An invalid or illegal string was specified"
if (false) {
casper.waitForSelector('//*[text()="Click me!"]', function() {
this.echo("I'm sure //*[text()='Click me!'] is available in the DOM");
});
}
casper.then(function(){
this.evaluate(function(){
var aelem = __utils__.getElementByXPath('//*[text()="Click me!"]');
aelem.click();
});
});
casper.then(function(){
casper.capture('TestCapture.png');
});
casper.run();
如果我 运行 JS 代码原样 - 即 waitForSelector
部分被 if(false)
禁用 - 那么一切 运行 都很好。
但是,如果我通过将 if(false)
更改为 if(true)
来启用该部分,我会得到:
$ SLIMERJSLAUNCHER=/usr/bin/firefox46 /home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules/casperjs/bin/casperjs --engine=slimerjs test_xpath.js
[info] [phantom] Starting...
[info] [phantom] Running suite: 5 steps
[debug] [phantom] opening url: http://localhost:8080/test_xpath.htm, HTTP GET
[debug] [phantom] Navigation requested: url=http://localhost:8080/test_xpath.htm, type=Undefined, willNavigate=true, isMainFrame=true
[debug] [phantom] url changed to "http://localhost:8080/test_xpath.htm"
[debug] [phantom] Successfully injected Casper client-side utilities
[info] [phantom] Step anonymous 2/6 http://localhost:8080/test_xpath.htm (HTTP 200)
URL changed http://localhost:8080/test_xpath.htm
[info] [phantom] Step anonymous 2/6: done in 235ms.
[info] [phantom] Step anonymous 3/6 http://localhost:8080/test_xpath.htm (HTTP 200)
website opened
[info] [phantom] Step anonymous 3/6: done in 258ms.
[info] [phantom] Step _step 4/6 http://localhost:8080/test_xpath.htm (HTTP 200)
[info] [phantom] Step _step 4/6: done in 276ms.
[error] [remote] findAll(): invalid selector provided "//*[text()="Click me!"]":SyntaxError: An invalid or illegal string was specified
[error] [remote] findAll(): invalid selector provided "//*[text()="Click me!"]":SyntaxError: An invalid or illegal string was specified
[error] [remote] findAll(): invalid selector provided "//*[text()="Click me!"]":SyntaxError: An invalid or illegal string was specified
[error] [remote] findAll(): invalid selector provided "//*[text()="Click me!"]":SyntaxError: An invalid or illegal string was specified
[error] [remote] findAll(): invalid selector provided "//*[text()="Click me!"]":SyntaxError: An invalid or illegal string was specified
....
我真的不明白,因为http://docs.casperjs.org/en/latest/modules/casper.html#waitforselector说:
Waits until an element matching the provided selector expression exists in remote DOM to process any next step
... 其中 http://docs.casperjs.org/en/latest/selectors.html 表示:
CasperJS makes a heavy use of selectors in order to work with the DOM, and can transparently use either CSS3 or XPath expressions.
所以,XPath 应该没问题 - 而且,我正在使用 完全相同的 XPATH 在:
var aelem = __utils__.getElementByXPath('//*[text()="Click me!"]');
...在那里它可以工作,但它失败了:
casper.waitForSelector('//*[text()="Click me!"]', function() { ....
为什么会这样——我哪里出错了?如果可能的话,我如何在 waitForSelector
中使用这个 XPath?
如果将字符串传递给 waitForSelector()
函数,它将被解释为 CSS 选择器 。要让它与 XPath 表达式一起工作,传入 object 显式指定选择器 type
:
selectorObject = {
type: 'xpath',
path: '//*[text()="Click me!"]'
}
casper.waitForSelector(selectorObject, function() {
// ...
});
你也可以用waitForText()
解决,示例。
我有这个 HTML 文件,test_xpath.htm
:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
<h1>Hello World!</h1>
<div>
<a href="http://whosebug.com">Click me!</a>
</div>
</body>
</html>
在这个文件的文件夹中,我 运行 PHP CLI > 5.4 作为服务器是这样的:
php -S localhost:8080
...因此 HTML 页面可在 http://localhost:8080/test_xpath.htm
.
然后我 运行 这个 SlimerJS 代码:
// run with:
// SLIMERJSLAUNCHER=/usr/bin/firefox46 /home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules/casperjs/bin/casperjs --engine=slimerjs test_xpath.js
var casper = require('casper').create({
verbose: true,
logLevel: 'debug',
userAgent: 'Mozilla/5.0 (X11; Linux i686; rv:43.0) Gecko/20100101 Firefox/43.0',
viewportSize: {width: 1024, height: 768},
pageSettings: {
loadImages: false,//The script is much faster when this field is set to false
loadPlugins: false,
}
});
casper.on("url.changed", function(){
this.then(function(){
this.echo("URL changed " + this.getCurrentUrl()); //getTitle());
});
});
casper.on('remote.message', function(message) {
this.echo('remote message caught: ' + message);
});
casper.start().thenOpen("http://localhost:8080/test_xpath.htm", function() {
console.log("website opened");
});
// set this to true to run - causes "[error] [remote] findAll(): invalid selector provided "//*[text()="Click me!"]":SyntaxError: An invalid or illegal string was specified"
if (false) {
casper.waitForSelector('//*[text()="Click me!"]', function() {
this.echo("I'm sure //*[text()='Click me!'] is available in the DOM");
});
}
casper.then(function(){
this.evaluate(function(){
var aelem = __utils__.getElementByXPath('//*[text()="Click me!"]');
aelem.click();
});
});
casper.then(function(){
casper.capture('TestCapture.png');
});
casper.run();
如果我 运行 JS 代码原样 - 即 waitForSelector
部分被 if(false)
禁用 - 那么一切 运行 都很好。
但是,如果我通过将 if(false)
更改为 if(true)
来启用该部分,我会得到:
$ SLIMERJSLAUNCHER=/usr/bin/firefox46 /home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules/casperjs/bin/casperjs --engine=slimerjs test_xpath.js
[info] [phantom] Starting...
[info] [phantom] Running suite: 5 steps
[debug] [phantom] opening url: http://localhost:8080/test_xpath.htm, HTTP GET
[debug] [phantom] Navigation requested: url=http://localhost:8080/test_xpath.htm, type=Undefined, willNavigate=true, isMainFrame=true
[debug] [phantom] url changed to "http://localhost:8080/test_xpath.htm"
[debug] [phantom] Successfully injected Casper client-side utilities
[info] [phantom] Step anonymous 2/6 http://localhost:8080/test_xpath.htm (HTTP 200)
URL changed http://localhost:8080/test_xpath.htm
[info] [phantom] Step anonymous 2/6: done in 235ms.
[info] [phantom] Step anonymous 3/6 http://localhost:8080/test_xpath.htm (HTTP 200)
website opened
[info] [phantom] Step anonymous 3/6: done in 258ms.
[info] [phantom] Step _step 4/6 http://localhost:8080/test_xpath.htm (HTTP 200)
[info] [phantom] Step _step 4/6: done in 276ms.
[error] [remote] findAll(): invalid selector provided "//*[text()="Click me!"]":SyntaxError: An invalid or illegal string was specified
[error] [remote] findAll(): invalid selector provided "//*[text()="Click me!"]":SyntaxError: An invalid or illegal string was specified
[error] [remote] findAll(): invalid selector provided "//*[text()="Click me!"]":SyntaxError: An invalid or illegal string was specified
[error] [remote] findAll(): invalid selector provided "//*[text()="Click me!"]":SyntaxError: An invalid or illegal string was specified
[error] [remote] findAll(): invalid selector provided "//*[text()="Click me!"]":SyntaxError: An invalid or illegal string was specified
....
我真的不明白,因为http://docs.casperjs.org/en/latest/modules/casper.html#waitforselector说:
Waits until an element matching the provided selector expression exists in remote DOM to process any next step
... 其中 http://docs.casperjs.org/en/latest/selectors.html 表示:
CasperJS makes a heavy use of selectors in order to work with the DOM, and can transparently use either CSS3 or XPath expressions.
所以,XPath 应该没问题 - 而且,我正在使用 完全相同的 XPATH 在:
var aelem = __utils__.getElementByXPath('//*[text()="Click me!"]');
...在那里它可以工作,但它失败了:
casper.waitForSelector('//*[text()="Click me!"]', function() { ....
为什么会这样——我哪里出错了?如果可能的话,我如何在 waitForSelector
中使用这个 XPath?
如果将字符串传递给 waitForSelector()
函数,它将被解释为 CSS 选择器 。要让它与 XPath 表达式一起工作,传入 object 显式指定选择器 type
:
selectorObject = {
type: 'xpath',
path: '//*[text()="Click me!"]'
}
casper.waitForSelector(selectorObject, function() {
// ...
});
你也可以用waitForText()
解决,示例