2

私はこの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://stackoverflow.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が言うので、私は本当にこれを理解していません:

指定されたセレクター式に一致する要素がリモート DOM に存在するまで待機して、次のステップを処理します

... http://docs.casperjs.org/en/latest/selectors.htmlの場所:

CasperJS は、DOM を操作するためにセレクターを多用し、透過的に CSS3 または XPath 式を使用できます。

したがって、XPath は問題ないはずです。さらに、次の場所でまったく同じXPATHを使用しています。

var aelem = __utils__.getElementByXPath('//*[text()="Click me!"]');

...そしてそこで動作しますが、失敗します:

casper.waitForSelector('//*[text()="Click me!"]', function() { ....

なぜこれが起こるのですか - どこが間違っているのでしょうか? また、可能であれば、この XPath を で使用するにwaitForSelectorはどうすればよいですか?

4

1 に答える 1

3

関数に文字列を渡すと、 CSS セレクターwaitForSelector()として解釈されます。XPath 式で動作させるには、selector を明示的に指定するオブジェクトを渡します。type

selectorObject = {
  type: 'xpath',
  path: '//*[text()="Click me!"]'
}
casper.waitForSelector(selectorObject, function() {
  // ...
});

こちらwaitForText()のサンプルでも解決できます。

于 2016-06-29T13:41:15.927 に答える