【发布时间】:2014-10-06 12:30:15
【问题描述】:
我必须使用 casperJS 将一个文件上传到客户服务器,现在在上传之前我需要模拟点击两个特定链接,这些链接(简单的 HTML 锚点)没有名称/id/类.. . (真的很丑的 HTML 代码)所以我只能通过它的文本内容来选择它。
如何使用querySelector 或querySelectorAll 方法找到它?
到目前为止,我可以想出以下(不成功的尝试):(
querySelector("a[text()='texttofind']");
querySelector("a[text='texttofind']");
querySelector("a[text=texttofind]");
所有建议后编辑
标题已更新 更具体地说明我似乎只与 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>
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>
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>
CasperJS 脚本
所有测试的开始都相等:
var casper = require('casper').create();
casper.start(serverName, function(){});
第一次测试 - @Ka0s 建议的 clicklabel
casper.then(function(){
this.withFrame('menu_b', function(){
this.clickLabel('clickhere', 'a');
});
});
结果:
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
即使我在测试代码的 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);
});
});
});
结果:
remote message caught: undefined
所以我认为 xPath 找不到元素。
第三次测试 - querySelectorAll 与@Brunis 建议的 for 循环
这是一个奇怪的行为,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]);
});
});
});
结果: 捕获的远程消息:javascript:alert('test')
我获得的是 href 代码而不是对象!如果我在小提琴中尝试这个例子,我会收到对象,我可以在它上面调用 onclick()。
【问题讨论】:
-
文本内容不是其父节点的属性;它本身就是一个节点类型。您将无法使用
querySelector执行此操作。您必须使用 JS 来检查每个a元素的文本内容,然后在找到匹配项后对其进行操作。 -
Palpatim 是对的,先找到所有的 a 元素,然后在一个简单的 for 循环中过滤掉不需要的元素。
-
为什么不用 XPath 来代替?
-
谢谢大家! @BoltClock 我如何在 casperJS 评估中使用 xPath?我无法使用它.. 我试试这个: var xPath = require('casper').selectXPath; this.evaluate(function(){element = xPath('//a[[text()="SampleText"]'); });但似乎不起作用:(我将 xPath 作为空引用
-
你从“我的代码”得到的错误不是我的代码,是你的 onchange 事件触发了警报。
标签: javascript css-selectors casperjs selectors-api