CasperJS/ Javascript Selecting Multiple Options

微笑、不失礼 提交于 2019-12-17 21:31:08

问题


Trying to scrape a website, where this is the generic HTML code

<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>

It is not enclosed by a form so I tried using the fill() function that casperjs provides but that did not work.

For single entries, I would usually casper.click() and that would work but this does not work for multiple entries even with looping

Also the website I am trying to scrape says hold "shift" to select multiple elements but then it can be done by also dragging and selecting.

I need to select multiple values


回答1:


This can be easily done by setting the selected property of each option element to true.

CasperJS by values

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);
};

Values must be strings. You can use it like this:

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

CasperJS by text

A similar function can be achieved when selecting by text:

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);
};

And use it like this:

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

PhantomJS by values

The same thing can be done for PhantomJS directly:

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);
};

and use it like this:

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

Triggering a change

It may be necessary to trigger a change event in case another element on the page depends on the

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);

Change event trigger was taken from here.



来源:https://stackoverflow.com/questions/30986521/casperjs-javascript-selecting-multiple-options

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!