casperJS如何使用querySelector或querySelectorAll通过特定的起始文本选择元素

Mar*_*rco 2 javascript css-selectors selectors-api casperjs

我必须使用casperJS将一个文件上传到客户服务器,现在在上传之前我需要模拟两个特定链接的点击,这些链接(简单的HTML锚点)没有名称/ id/class ...(真的丑陋的HTML代码)所以我有唯一的选择,通过它的文本内容来选择它.

如何使用querySelectorquerySelectorAll方法找到它?

到目前为止,我可以提出以下(不成功的尝试):(

querySelector("a[text()='texttofind']");
querySelector("a[text='texttofind']");
querySelector("a[text=texttofind]");
Run Code Online (Sandbox Code Playgroud)

编辑后的所有建议

TITLE UPDATED 更具体地说明我的问题,似乎只与casperjs有关

平台 - Windows 7 - CasperJS版本1.1.0-beta3 - phantomjs版本1.9.7 - Python 2.7

所以,可能我太愚蠢了:(现在我发布一个完整的例子,遗憾地对我不起作用:(

HTML主索引

<html>
<head>
<title>TEST Main Page</title>
</head>
<frameset cols="100,100" >
    <frame name="menu_a" src="menu_1.html">
    <frame name="menu_b" src="menu_2.html">
</frameset>
</html>
Run Code Online (Sandbox Code Playgroud)

HTML menu_1.html

<html>
<head>
<title>TEST Menu 1</title>
</head>
<body style="background-color:red;">
<h3>Menu 1</h3>
<select onchange="javscript:alert('test')" id="test" size="1" name="systemID">
    <option value="0">---</option>
    <option selected="selected" value="1">TestMenu1            </option>
    <option value="17">TestMenu2                               </option>
</select>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

HTML menu_2.html

<html>
<head>
<title>TEST Menu 1</title>
</head>
<body style="background-color:orange;">
<h3>Menu 2</h3>
 <a href="javascript:alert('test')"><b>clickhere   </b></a>
 <a href="javascript:alert('noclickhere')"><b>NoClickHere   </b></a>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

CasperJS脚本

对所有测试开始相同:

var casper = require('casper').create();

casper.start(serverName, function(){});
Run Code Online (Sandbox Code Playgroud)

第一次测试 - 按@ Ka0s的建议点击标签

casper.then(function(){
    this.withFrame('menu_b', function(){
        this.clickLabel('clickhere', 'a');
    });
});
Run Code Online (Sandbox Code Playgroud)

结果:

CasperError: Cannot dispatch mousedown event on nonexistent selector: xpath selector: //a[text()="test"]
  /bin/casperjs/modules/casper.js:1355 in mouseEvent
  /bin/casperjs/modules/casper.js:462 in click
  /bin/casperjs/modules/casper.js:487 in clickLabel
  /test.js:90
  /bin/casperjs/modules/casper.js:1553 in runStep
  /bin/casperjs/modules/casper.js:399 in checkStep
Run Code Online (Sandbox Code Playgroud)

这不起作用,即使我清理字符串删除我的测试代码上的clickhere字符串末尾的空格.

第二次测试 - 由@ArtjomB建议的xPath

casper.then(function(){
    this.withFrame('menu_b', function(){
    this.evaluate(function(){
     var element = __utils__.getElementByXPath("//a[starts-with(text(),'clickhere')]");
     console.log(element);
    });
 });
});
Run Code Online (Sandbox Code Playgroud)

结果:

remote message caught: undefined
Run Code Online (Sandbox Code Playgroud)

所以我想xPath找不到元素.

第三次测试 - 使用@Brunis建议的for循环的querySelectorAll

这是一个奇怪的beaviour,casperJS返回href的内容而不是对象,这似乎不是下面的代码错误,但我的实现或其他问题.

casper.then(function(){
    this.withFrame('menu_b', function(){
        this.evaluate(function(){
        var as = document.querySelectorAll("a");
        var match = "clickhere";
        var elems = [];     
        for (var i=0; i<as.length; i++){
            if (as[i].textContent === match) {
                elems.push(as[i]);
            }
        }
        console.log(elems[0]);
    });
 });
});
Run Code Online (Sandbox Code Playgroud)

结果:捕获了远程消息:javascript:alert('test')

我获得的href代码不是对象!如果我在小提琴中尝试这个例子,我会收到该对象,我可以在其上调用onclick().

Bru*_*nis 5

这是一个与您想要的链接文本匹配的简单循环,并将它们添加到数组中:

html:

<div>
    <a name="test">not this one</a>
    <a name="test">not this one</a>
    <a name="test">not this one</a>
    <a name="test">not this one</a>
    <a name="test">this one</a>
</div>
Run Code Online (Sandbox Code Playgroud)

和脚本:

var as = document.querySelectorAll("a");
var match = "this one";
var elems = [];

for (var i=0; i<as.length; i++){
    if (as[i].textContent === match) {
        elems.push(as[i]);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在你在elems数组中有匹配的元素.

在这里小提琴:http://jsfiddle.net/0pLd8s9r/