CasperJS/ Javascript 选择多个选项

CasperJS/ Javascript Selecting Multiple Options

正在尝试抓取一个网站,这是通用 HTML 代码

<select id="xxx" multiple name="zzz">
<option value="123">xaxaxa</option>
<option value="124">zazaza</option>
<option value="125">ajajaj</option>
<option value="126">azzzsa</option>
</select>

它没有包含在表单中,所以我尝试使用 casperjs 提供的 fill() 函数,但没有用。

对于单个条目,我通常会 casper.click() 并且这会起作用,但这不适用于多个条目,即使使用循环

另外,我试图抓取的网站说保持 "shift" 到 select 多个元素,但也可以通过拖动和 selecting 来完成。

我需要select多个值

这可以通过将每个选项元素的 selected 属性 设置为 true 来轻松完成。

CasperJS 值

casper.selectOptionsByValues = function(selectCssSelector, values){
    this.evaluate(function(selector, values){
        [].forEach.call(document.querySelector(selector).options, function(opt){
            if (values.indexOf(opt.value) !== -1) {
                opt.selected = true;
            }
        });
    }, selectCssSelector, values);
};

值必须是字符串。你可以这样使用它:

casper.selectOptionsByValues("#xxx", [ "124", "125" ]);

CasperJS 文本

通过文本选择可以实现类似的功能:

casper.selectOptionsByTexts = function(selectCssSelector, texts){
    texts = texts.map(function(t){ return t.trim() });
    this.evaluate(function(selector, texts){
        [].forEach.call(document.querySelector(selector).options, function(opt){
            if (texts.indexOf(opt.text.trim()) !== -1) {
                opt.selected = true;
            }
        });
    }, selectCssSelector, texts);
};

并像这样使用它:

casper.selectOptionsByTexts ("#xxx", [ "zazaza", "ajajaj" ]);

PhantomJS 值

可以直接对 PhantomJS 做同样的事情:

function selectOptionsByValues(page, selectCssSelector, values){
    page.evaluate(function(selector, values){
        [].forEach.call(document.querySelector(selector).options, function(opt){
            if (values.indexOf(opt.value) !== -1) {
                opt.selected = true;
            }
        });
    }, selectCssSelector, values);
};

并像这样使用它:

selectOptionsByValues(page, "#xxx", [ "124", "125" ]);

触发改变

如果页面上的另一个元素依赖于

,则可能需要触发更改事件
this.evaluate(function(selector, values){
    [].forEach.call(...);

    var evt = document.createEvent("UIEvents"); // or "HTMLEvents"
    evt.initUIEvent("change", true, true);
    document.querySelector(selector).dispatchEvent(evt);
}, selectCssSelector, values);

更改事件触发器取自 here