CasperJS:在由 <div> 和动态 类 组成的下拉菜单中选择一个选项
CasperJS : Selecting an option in dropdown menu made of <div> and dynamic classes
在这里经过多次尝试和搜索后,我无法帮助自己修复我的 CasperJS 脚本。
基本上,我正在抓取列出大量页面的网站的页面。成功登录后可以过滤主页(这部分完成),然后,我想在下拉菜单中 select 一个选项来过滤掉它们。这是下拉菜单的 HTML 代码:
<div class="sg-dropdown brn-filters__status js-filter-status js-status-toggle">
<div class="sg-dropdown__icon"></div>
<div class="sg-dropdown__hole sg-dropdown__hole--inactive">
<div class="sg-dropdown__item-text sg-dropdown__item-text--active js-main-status"> Unanswered </div>
</div>
<div class="sg-dropdown__hole sg-dropdown__hole--active">
<div class="sg-dropdown__item-text sg-dropdown__item-text--active"> Select </div>
</div>
<div class="sg-dropdown__items js-status-list">
<div class="sg-dropdown__item-hole ">
<div class="sg-dropdown__item-text"> All </div>
</div>
<div class="sg-dropdown__item-hole chosen-status">
<div class="sg-dropdown__item-text"> Unanswered </div>
</div>
<div class="sg-dropdown__item-hole ">
<div class="sg-dropdown__item-text"> Unresolved </div>
</div>
<div class="sg-dropdown__item-hole ">
<div class="sg-dropdown__item-text"> Resolved </div>
</div>
</div>
</div>
如何使用 CasperJS 在这个下拉菜单中 select "Resolved"?
我注意到的潜在线索:
- 默认情况下,应用过滤器 "Unanswered" (.js-main-status
我猜是这样定义的)。
- 可能无关紧要,但只要我
打开下拉菜单,第一个
<div>
将其 class 更改为
sg-dropdown brn-filters__status js-filter-status
js-status-toggle--opened
- 当我 select 过滤器(比方说 "Resolved")时,
chosen-status
被添加到其 sg-dropdown__item-hole
父级 class。关于这一点,sg-dropdown__item-hole
以双 space 完成,最后一个在单击选项时被 chosen-status
替换。
我尝试了很多代码行,从简单的 .click()
方法到涉及 evaluate()
、sendKeys
的更复杂的代码块(我之前使用它来执行登录),querySelector().selectedIndex
,fetchText()
使用 XPath,等等...
我的问题,并且与此页面上的其他按钮重复出现,是我必须只处理 <div>
个元素,这些元素几乎只有 class执行事件(单击、滚动等)。
感谢您的帮助!
更新#1
我试过这些 LOC(基于此 thread):
casper.then(function () {
if (this.exists('div.sg-dropdown.brn-filters__status.js-filter-status.js-status-toggle')) {
this.click('div.sg-dropdown.brn-filters__status.js-filter-status.js-status-toggle');
console.log('click dropdown');
}
else {
console.log('no click dropdown');
}
});
casper.wait(9000, function() {
console.log('wait 9 seconds 1/2');
});
casper.then(function() {
if (this.exist('div.sg-dropdown.brn-filters__status.js-filter-status.js-status-toggle.sg-dropdown--opened > div.sg-dropdown__items.js-status-list > div:nth-child(4)')) {
this.click('div.sg-dropdown.brn-filters__status.js-filter-status.js-status-toggle.sg-dropdown--opened > div.sg-dropdown__items.js-status-list > div:nth-child(4)');
console.log('click Resolved');
}
else {
console.log('no click Resolved');
}
})
casper.wait(9000, function() {
this.capture('test.png');
console.log('wait 9 seconds 2/2');
})
第一步似乎工作正常,因为我可以在控制台中看到提示的 wait 9 seconds 1/2
消息。但是,如果我捕获这一步,我将看不到打开的下拉菜单。
第二步彻底失败。我首先认为这是由于 sg-dropdown brn-filters__status js-filter-status js-status-toggle
class 末尾缺少 --opened
但没有任何效果,因为我总是得到同样的错误:
TypeError: undefined is not a constructor (evaluating 'this.exist')
在之前的一些测试中,当我试图将“已解决”读入 <div>
时,我返回了值 undefined
。我什至在控制台中几乎没有返回任何内容,比如空白 spaces 并且没有错误和 运行.
的结尾
有人知道吗?
更新#2
我刚刚添加了一个if条件来测试sg-dropdown brn-filters__status js-filter-status js-status-toggle--opened
class点击下拉后似乎不存在
所以第 1 步甚至都不起作用,现在我有点迷路了
我最终找到了这个:https://github.com/casperjs/casperjs/issues/1390 有几个指向 Stack Overflow 线程的链接,@Artjom-b 经常回答。
我似乎陷入了死胡同,因为 CasperJS 不提供从下拉列表中选择选项的本机支持,但在我的情况下更糟,因为我没有 <select>
也没有 <option>
。我确信有一种方法可以更新 类 并因此重新加载页面,但它现在超出了我的范围。
无论如何,我找到了另一种访问我正在寻找的数据的方法,我现在正在研究如何更快地执行报废!
在这里经过多次尝试和搜索后,我无法帮助自己修复我的 CasperJS 脚本。
基本上,我正在抓取列出大量页面的网站的页面。成功登录后可以过滤主页(这部分完成),然后,我想在下拉菜单中 select 一个选项来过滤掉它们。这是下拉菜单的 HTML 代码:
<div class="sg-dropdown brn-filters__status js-filter-status js-status-toggle">
<div class="sg-dropdown__icon"></div>
<div class="sg-dropdown__hole sg-dropdown__hole--inactive">
<div class="sg-dropdown__item-text sg-dropdown__item-text--active js-main-status"> Unanswered </div>
</div>
<div class="sg-dropdown__hole sg-dropdown__hole--active">
<div class="sg-dropdown__item-text sg-dropdown__item-text--active"> Select </div>
</div>
<div class="sg-dropdown__items js-status-list">
<div class="sg-dropdown__item-hole ">
<div class="sg-dropdown__item-text"> All </div>
</div>
<div class="sg-dropdown__item-hole chosen-status">
<div class="sg-dropdown__item-text"> Unanswered </div>
</div>
<div class="sg-dropdown__item-hole ">
<div class="sg-dropdown__item-text"> Unresolved </div>
</div>
<div class="sg-dropdown__item-hole ">
<div class="sg-dropdown__item-text"> Resolved </div>
</div>
</div>
</div>
如何使用 CasperJS 在这个下拉菜单中 select "Resolved"?
我注意到的潜在线索:
- 默认情况下,应用过滤器 "Unanswered" (.js-main-status 我猜是这样定义的)。
- 可能无关紧要,但只要我
打开下拉菜单,第一个
<div>
将其 class 更改为sg-dropdown brn-filters__status js-filter-status js-status-toggle--opened
- 当我 select 过滤器(比方说 "Resolved")时,
chosen-status
被添加到其sg-dropdown__item-hole
父级 class。关于这一点,sg-dropdown__item-hole
以双 space 完成,最后一个在单击选项时被chosen-status
替换。
我尝试了很多代码行,从简单的 .click()
方法到涉及 evaluate()
、sendKeys
的更复杂的代码块(我之前使用它来执行登录),querySelector().selectedIndex
,fetchText()
使用 XPath,等等...
我的问题,并且与此页面上的其他按钮重复出现,是我必须只处理 <div>
个元素,这些元素几乎只有 class执行事件(单击、滚动等)。
感谢您的帮助!
更新#1
我试过这些 LOC(基于此 thread):
casper.then(function () {
if (this.exists('div.sg-dropdown.brn-filters__status.js-filter-status.js-status-toggle')) {
this.click('div.sg-dropdown.brn-filters__status.js-filter-status.js-status-toggle');
console.log('click dropdown');
}
else {
console.log('no click dropdown');
}
});
casper.wait(9000, function() {
console.log('wait 9 seconds 1/2');
});
casper.then(function() {
if (this.exist('div.sg-dropdown.brn-filters__status.js-filter-status.js-status-toggle.sg-dropdown--opened > div.sg-dropdown__items.js-status-list > div:nth-child(4)')) {
this.click('div.sg-dropdown.brn-filters__status.js-filter-status.js-status-toggle.sg-dropdown--opened > div.sg-dropdown__items.js-status-list > div:nth-child(4)');
console.log('click Resolved');
}
else {
console.log('no click Resolved');
}
})
casper.wait(9000, function() {
this.capture('test.png');
console.log('wait 9 seconds 2/2');
})
第一步似乎工作正常,因为我可以在控制台中看到提示的 wait 9 seconds 1/2
消息。但是,如果我捕获这一步,我将看不到打开的下拉菜单。
第二步彻底失败。我首先认为这是由于 sg-dropdown brn-filters__status js-filter-status js-status-toggle
class 末尾缺少 --opened
但没有任何效果,因为我总是得到同样的错误:
TypeError: undefined is not a constructor (evaluating 'this.exist')
在之前的一些测试中,当我试图将“已解决”读入 <div>
时,我返回了值 undefined
。我什至在控制台中几乎没有返回任何内容,比如空白 spaces 并且没有错误和 运行.
有人知道吗?
更新#2
我刚刚添加了一个if条件来测试sg-dropdown brn-filters__status js-filter-status js-status-toggle--opened
class点击下拉后似乎不存在
所以第 1 步甚至都不起作用,现在我有点迷路了
我最终找到了这个:https://github.com/casperjs/casperjs/issues/1390 有几个指向 Stack Overflow 线程的链接,@Artjom-b 经常回答。
我似乎陷入了死胡同,因为 CasperJS 不提供从下拉列表中选择选项的本机支持,但在我的情况下更糟,因为我没有 <select>
也没有 <option>
。我确信有一种方法可以更新 类 并因此重新加载页面,但它现在超出了我的范围。
无论如何,我找到了另一种访问我正在寻找的数据的方法,我现在正在研究如何更快地执行报废!