0

I am trying to scrape a web site that waits for a button click from a user. I could not find the proper button to cause selenium to do the click. Here is the web page before the click. It is a simple web page so it is not long. I see in the body the following HTML:

<div id="startStopBtn" onclick="startStop()" class=""></div> 

and in the header there is a function

startStop()

but I could not figure out how to initiate it. Any help will be appreciated.

<html><head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, user-scalable=no">
<title>ITC Speedtest</title>
<style type="text/css">
    html,body{
        border:none; padding:0; margin:0;
        background:#fff;
        color:#1e73be;
    }
    body{
        text-align:center;
        font-family:"Roboto",sans-serif;
    }
    h1{
        color:#1e73be;
    }
    #startStopBtn{
        display:inline-block;
        margin:0 auto;
        color:#6060AA;
        background-color:rgba(0,0,0,0);
        border:0.15em solid #6060FF;
        border-radius:0.3em;
        transition:all 0.3s;
        box-sizing:border-box;
        width:8em; height:3em;
        line-height:2.7em;
        cursor:pointer;
        box-shadow: 0 0 0 rgba(0,0,0,0.1), inset 0 0 0 rgba(0,0,0,0.1);
    }
    #startStopBtn:hover{
        box-shadow: 0 0 2em rgba(0,0,0,0.1), inset 0 0 1em rgba(0,0,0,0.1);
    }
    #startStopBtn.running{
        background-color:#FF3030;
        border-color:#FF6060;
        color:#FFFFFF;
    }
    #startStopBtn:before{
        content:"Start";
    }
    #startStopBtn.running:before{
        content:"Abort";
    }
    #test{
        margin-top:2em;
        margin-bottom:12em;
    }
    div.testArea{
        display:inline-block;
        width:16em;
        height:12.5em;
        position:relative;
        box-sizing:border-box;
    }
    div.testName{
        position:absolute;
        top:0.1em; left:0;
        width:100%;
        font-size:1.4em;
        z-index:9;
    }
    div.meterText{
        position:absolute;
        bottom:1.55em; left:0;
        width:100%;
        font-size:2.5em;
        z-index:9;
    }
    div.meterText:empty:before{
        content:"0.00";
    }
    div.unit{
        position:absolute;
        bottom:2em; left:0;
        width:100%;
        z-index:9;
    }
    div.testArea canvas{
        position:absolute;
        top:0; left:0; width:100%; height:100%;
        z-index:1;
    }
    div.testGroup{
        display:inline-block;
    }
    @media all and (max-width:65em){
        body{
            font-size:1.5vw;
        }
    }
    @media all and (max-width:40em){
        body{
            font-size:0.8em;
        }
        div.testGroup{
            display:block;
            margin: 0 auto;
        }
    }

</style>
<script type="text/javascript">
function I(id){return document.getElementById(id);}
var meterBk="#E0E0E0";
var dlColor="#6060AA",
    ulColor="#309030",
    pingColor="#AA6060",
    jitColor="#AA6060";
var progColor="#EEEEEE";

//CODE FOR GAUGES
function drawMeter(c,amount,bk,fg,progress,prog){
    var ctx=c.getContext("2d");
    var dp=window.devicePixelRatio||1;
    var cw=c.clientWidth*dp, ch=c.clientHeight*dp;
    var sizScale=ch*0.0055;
    if(c.width==cw&&c.height==ch){
        ctx.clearRect(0,0,cw,ch);
    }else{
        c.width=cw;
        c.height=ch;
    }
    ctx.beginPath();
    ctx.strokeStyle=bk;
    ctx.lineWidth=16*sizScale;
    ctx.arc(c.width/2,c.height-58*sizScale,c.height/1.8-ctx.lineWidth,-Math.PI*1.1,Math.PI*0.1);
    ctx.stroke();
    ctx.beginPath();
    ctx.strokeStyle=fg;
    ctx.lineWidth=16*sizScale;
    ctx.arc(c.width/2,c.height-58*sizScale,c.height/1.8-ctx.lineWidth,-Math.PI*1.1,amount*Math.PI*1.2-Math.PI*1.1);
    ctx.stroke();
    if(typeof progress !== "undefined"){
        ctx.fillStyle=prog;
        ctx.fillRect(c.width*0.3,c.height-16*sizScale,c.width*0.4*progress,4*sizScale);
    }
}
function mbpsToAmount(s){
    return 1-(1/(Math.pow(1.3,Math.sqrt(s))));
}
function msToAmount(s){
    return 1-(1/(Math.pow(1.08,Math.sqrt(s))));
}

//SPEEDTEST AND UI CODE
var w=null; //speedtest worker
var data=null; //data from worker
function startStop(){
    if(w!=null){
        //speedtest is running, abort
        w.postMessage('abort');
        w=null;
        data=null;
        I("startStopBtn").className="";
        initUI();
    }else{
        //test is not running, begin
        w=new Worker('speedtest_worker.min.js');
        w.postMessage('start'); //Add optional parameters as a JSON object to this command
        I("startStopBtn").className="running";
        w.onmessage=function(e){
            data=e.data.split(';');
            var status=Number(data[0]);
            if(status>=4){
                //test completed
                I("startStopBtn").className="";
                w=null;
                updateUI(true);
            }
        };
    }
}
//this function reads the data sent back by the worker and updates the UI
function updateUI(forced){
    if(!forced&&(!data||!w)) return;
    var status=Number(data[0]);
//  I("ip").textContent=data[4];
    I("dlText").textContent=(status==1&&data[1]==0)?"...":data[1];
    drawMeter(I("dlMeter"),mbpsToAmount(Number(data[1]*(status==1?oscillate():1))),meterBk,dlColor,Number(data[6]),progColor);
    I("ulText").textContent=(status==3&&data[2]==0)?"...":data[2];
    drawMeter(I("ulMeter"),mbpsToAmount(Number(data[2]*(status==3?oscillate():1))),meterBk,ulColor,Number(data[7]),progColor);
    I("pingText").textContent=data[3];
    drawMeter(I("pingMeter"),msToAmount(Number(data[3]*(status==2?oscillate():1))),meterBk,pingColor,Number(data[8]),progColor);
}
function oscillate(){
    return 1+0.02*Math.sin(Date.now()/100);
}
//poll the status from the worker (this will call updateUI)
setInterval(function(){
    if(w) w.postMessage('status');
},200);
//update the UI every frame
window.requestAnimationFrame=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.msRequestAnimationFrame||(function(callback,element){setTimeout(callback,1000/60);});
function frame(){
    requestAnimationFrame(frame);
    updateUI();
}
frame(); //start frame loop
//function to (re)initialize UI
function initUI(){
    drawMeter(I("dlMeter"),0,meterBk,dlColor,0);
    drawMeter(I("ulMeter"),0,meterBk,ulColor,0);
    drawMeter(I("pingMeter"),0,meterBk,pingColor,0);
    I("dlText").textContent="";
    I("ulText").textContent="";
    I("pingText").textContent="";
//  I("ip").textContent="";
}

</script>
</head>
<body>
<h1>ITC Speedtest</h1>
<div id="startStopBtn" onclick="startStop()" class=""></div>
<div id="test">
    <div class="testGroup">
        <div class="testArea">
            <div class="testName">Download</div>
            <canvas id="dlMeter" class="meter" width="223" height="174"></canvas>
            <div id="dlText" class="meterText">162.74</div>
            <div class="unit">Mbps</div>
        </div>
        <div class="testArea">
            <div class="testName">Upload</div>
            <canvas id="ulMeter" class="meter" width="223" height="174"></canvas>
            <div id="ulText" class="meterText">9.85</div>
            <div class="unit">Mbps</div>
        </div>
    </div>
    <div class="testGroup">
        <div class="testArea">
            <div class="testName">Ping</div>
            <canvas id="pingMeter" class="meter" width="223" height="174"></canvas>
            <div id="pingText" class="meterText">23.83</div>
            <div class="unit">ms</div>
        </div>
    </div>
    <div id="ipArea">
        IP Address: <span id="ip">100.103.124.12</span>
    </div>
</div>
<script type="text/javascript">setTimeout(initUI,100);</script>

</body></html>

2 Answers 2

1

To click on the element you can use either of the following Locator Strategies:

  • Using css_selector:

    driver.find_element(By.CSS_SELECTOR, "div#startStopBtn[onclick^='startStop']").click()
    
  • Using xpath:

    driver.find_element(By.XPATH, "//h1[text()='ITC Speedtest']//following-sibling::div[@id='startStopBtn' and starts-with(@onclick, 'startStop')]").click()
    

Ideally, to click on the element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:

  • Using CSS_SELECTOR:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div#startStopBtn[onclick^='startStop']"))).click()
    
  • Using XPATH:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//h1[text()='ITC Speedtest']//following-sibling::div[@id='startStopBtn' and starts-with(@onclick, 'startStop')]"))).click()
    
  • Note: You have to add the following imports :

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    
Sign up to request clarification or add additional context in comments.

Comments

0

You can Use Selenium -

driver = webdriver.Chrome("/usr/local/bin/chromedriver")
driver.get("URL")
button = driver.find_element_by_xpath("XPATH_BUTTON")
button.click()

Put in your URL, Place of chrome in your PC, and XPATH of the button.

3 Comments

I wanted to do it but I could not find the button so I do not know it's XPath
I tried the above code with xpath of 'startStopBtn' but got an error "'list' object has no attribute 'click'"
It looks like my xpath is wrong but I do not know how to set it right

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.