问题
Need help
I am scraping data from this website which has a form that contains three selectlists interconnected to each other that is if the any option from the from the first select list is selected this function is called onchange="Javascript:submitForm2();
and the second selectlist is populated.
And subsequently if an option from the second selectlist is selected the same js function is called onchange="Javascript:submitForm2();"
And finally two submit buttons for this form each call different js function which populate the result. So I checked out the docs and I did not find any info about selectlists.
Three dynamically changing select lists interconnected to each other
<select name="s1" onChange="Javascript:submitForm2();" style="width: 150px" width="150">
<select name="s2" onChange="Javascript:submitForm2();" style="width: 300px" width="300">
<select name="s3" style="width:300px" width="300">
And the form has two submit buttons
Tried with these codes this.click('select#s1 option[value="26"]'); this.debugHTML();
Gives me this error CasperError: Cannot dispatch click event on nonexistent selector: select#s1 option[value="26"]
I also tried document.querySelector('select[name="s1"]').setAttribute('value', "26");
Which gives TypeError: 'null' is not an object (evaluating'document.querySelector('select[name="s1"]').setAttribute')
回答1:
Sharing the solution script.
I Iterated upon the select lists n*n*n
times along with dates and two buttons.
require 'rubygems'
require 'capybara-webkit'
require 'capybara/dsl'
require 'nokogiri'
include Capybara::DSL
Capybara.current_driver = :webkit
visit("http://thewebsite.com")
op0_xpath = "//*[@name='selectlist0']/option[1]"
op0 = find(:xpath, op0_xpath).text
select(op0, :from => 'selectlist0')
page.evaluate_script("$('body').submitForm2()")
sleep(2)
op1_xpath = "//*[@name='selectlist1']/option[1]"
op1 = find(:xpath, op1_xpath).text
select(op1, :from => 'selectlist1')
page.evaluate_script("$('body').submitForm2()")
sleep(2)
op2_xpath = "//*[@name='selectlist2']/option[1]"
op2 = find(:xpath, op2_xpath).text
select(op2, :from => 'selectlist2')
sleep(2)
find(:xpath, "//input[@name='curYear']").set "2012"
find(:xpath, "//input[@name='curMonth']").set "10"
find(:xpath, "//input[@name='curDay']").set "09"
click_button('button1')
page.evaluate_script("$('body').submitForm()")
回答2:
You can do something like this you have a form with three interconnected selects.
var valueFirstSelect = 125;
var valueSecondSelect = 6;
var valueThirdSelect = 47;
//create casper object
var casper = require('casper').create({
loadImages:false,
verbose: true,
logLevel: 'debug'
});
//open url
casper.start('http://thewebsite.com');
casper.then(function(){
//select option on first select
this.evaluate(function(selectValue){
document.querySelector('select[name=s1]').value = selectValue;
return true;
},valueFirstSelect);
//firing onchange event to populate the second select
this.evaluate(function() {
var element = document.querySelector('select[name=s1]');
var evt = document.createEvent('HTMLEvents');
evt.initEvent('change', false, true);
element.dispatchEvent(evt);
});
//wait until the second select is populated
this.waitFor(function check() {
return this.evaluate(function() {
return document.querySelectorAll('select[name=s2] option').length > 1;
});
}, function then() {
//select option on second select
this.evaluate(function(selectValue){
document.querySelector('select[name=s2]').value = selectValue;
return true;
},valueSecondSelect);
//firing onchange event to populate the third select
this.evaluate(function() {
var element = document.querySelector('select[name=s2]');
var evt = document.createEvent('HTMLEvents');
evt.initEvent('change', false, true);
element.dispatchEvent(evt);
});
//wait until the third select is populated
this.waitFor(function check() {
return this.evaluate(function() {
return document.querySelectorAll('select[name=s3] option').length > 1;
});
}, function then() {
//select option on third select
this.evaluate(function(selectValue){
document.querySelector('select[name=s3]').value = selectValue;
return true;
},valueThirdSelect);
//click submit button
casper.thenClick('form.items input[type="submit"]', function() {
/* Do something after click */
});
});
});
});
casper.run(function() {
//finish execution script
this.exit();
});
If you context page includes jQuery library, this code could be different (smaller and cleaner).
Here there is example using casperjs and jQuery with dynamic selectlists.
CasperJs and Jquery with chained Selects
来源:https://stackoverflow.com/questions/12780014/casperjs-dynamic-selectlists