【问题标题】:CasperJS dynamic selectlistsCasperJS 动态选择列表
【发布时间】:2012-10-08 10:39:15
【问题描述】:

需要帮助

我正在从该网站抓取数据,该表单包含三个相互连接的选择列表,如果选择第一个选择列表中的任何选项,则此函数称为 onchange="Javascript:submitForm2(); 并填充第二个选择列表.

随后,如果从第二个选择列表中选择了一个选项,则调用相同的 js 函数 onchange="Javascript:submitForm2();" 最后,此表单的两个提交按钮分别调用不同的 js 函数来填充结果。所以我查看了文档,但没有找到任何关于选择列表的信息。

三个相互连接的动态变化的选择列表

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

并且表单有两个提交按钮

尝试使用这些代码this.click('select#s1 option[value="26"]'); this.debugHTML();

给我这个错误CasperError: Cannot dispatch click event on nonexistent selector: select#s1 option[value="26"]

我也试过document.querySelector('select[name="s1"]').setAttribute('value', "26"); 这给了TypeError: 'null' is not an object (evaluating'document.querySelector('select[name="s1"]').setAttribute')

【问题讨论】:

  • 为什么要尝试模仿某人使用表单的操作,只需使用 GET 或 POST 将值直接注入服务器。
  • 完成。通过 capybara-webkit 的真棒

标签: javascript ruby web-scraping capybara casperjs


【解决方案1】:

分享解决方案脚本。 我迭代了选择列表n*n*n 次以及日期和两个按钮。

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

    你可以做这样的事情,你有一个包含三个相互关联的选择的表单。

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

    如果您的上下文页面包含 jQuery 库,则此代码可能会有所不同(更小更简洁)。

    这里有一个使用 casperjs 和 jQuery 与动态选择列表的示例。

    CasperJs and Jquery with chained Selects

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-11
      • 2014-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-30
      相关资源
      最近更新 更多