【Python + Selenium】之JS定位总结(以及CSS一些定位方法)

感谢:

Python+Selenium 脚本中的一些js的用法汇总

 

1、滚动条

driver.set_window_size(500,500)
js = "window.scrollTo(0,200)"  #左:距左边横滚、右:距上边竖滚
driver.execute_script(js)

 

2、获取元素的值

button = driver.find_element_by_css_selector("#su")  #定位按钮
input = driver.find_element_by_css_selector("#kw")  #定位输入框
#return:返回值  arguments[1]对应的是第二个参数,可以理解为python里的%s传参,与之类似
js = "return arguments[1].value;"   #获取第二个属性【button】的值
val = driver.execute_script(js,input,button)
print(val)

#返回结果:百度一下

 

3、页面加弹出窗口提示

driver.execute_script("alert('hello world!')")

扩展alert:

#接受提示信息 
from selenium.webdriver.common.alert import Alert 
driver.switch_to_alert().accept() t
=driver.switch_to_alert() print (t.text) t.accept()
#针对js  非div 元素的 alert 弹出事件 可以用:
from selenium.webdriver import ActionChains

alert = driver.switch_to_alert()
#模拟键盘Enter 键
ActionChains(driver).send_keys(Keys.ENTER).perform()

 

4、选择日期控件

参考自制一个日期控件:《带时间的日历控件

js="$('#SystemDate').val('2017-07-21');"  
driver.execute_script(js)

但是还有一种情况,日期控件有readonly属性:

参考文章:《selenium+Python(Js处理日历控件)

datePlugin.js

复制代码
/**
 * Created with PyCharm.
 * User: Administrator
 * Date: 17-8-19
 * Time: 下午9:23
 * To change this template use File | Settings | File Templates.
 */
var cal;
var isFocus=false; //是否为焦点
var pickMode ={
    "second":1,
    "minute":2,
    "hour":3,
    "day":4,
    "month":5,
    "year":6  };
 
var topY=0,leftX=0;  //自定义定位偏移量
//选择日期,通过 ID 来选日期
 
function SelectDateById(id,strFormat,x,y)
{
    var obj = document.getElementById(id);
    if(obj == null){return false;}
    obj.focus();
    if(obj.onclick != null){obj.onclick();}
    else if(obj.click != null){obj.click();}
    else{SelectDate(obj,strFormat,x,y)}
}
 
//选择日期
function SelectDate(obj,strFormat,x,y)
{
 
    leftX =(x == null) ? leftX : x;
    topY  =(y == null) ? topY : y;//自定义定位偏移量
    if(document.getElementById("ContainerPanel")==null){InitContainerPanel();}
    var date = new Date();
    var by = date.getFullYear()-50;  //最小值 → 50 年前
    var ey = date.getFullYear()+50;  //最大值 → 50 年后
    //cal = new Calendar(by, ey,1,strFormat);    //初始化英文版,0 为中文版
    cal = (cal==null) ? new Calendar(by, ey, 0) : cal;    //不用每次都初始化 2006-12-03 修正
    cal.DateMode =pickMode["second"]; //复位
    if(strFormat.indexOf('s')< 0) {cal.DateMode =pickMode["minute"];}//精度为分
    if(strFormat.indexOf('m')< 0) {cal.DateMode =pickMode["hour"];}//精度为时
    if(strFormat.indexOf('h')< 0) {cal.DateMode =pickMode["day"];}//精度为日
    if(strFormat.indexOf('d')< 0) {cal.DateMode =pickMode["month"];}//精度为月
    if(strFormat.indexOf('M')< 0) {cal.DateMode =pickMode["year"];}//精度为年
    if(strFormat.indexOf('y')< 0) {cal.DateMode =pickMode["second"];}//默认精度为秒
    cal.dateFormatStyleOld = cal.dateFormatStyle;
    cal.dateFormatStyle = strFormat;
    cal.show(obj);
}
/**//**//**//**//**//**//**//**
 * 返回日期
 * @param d the delimiter
 * @param p the pattern of your date
 根据用户指定的 style 来确定;
 */
String.prototype.toDate = function(style) {
    var y = this.substring(style.indexOf('y'),style.lastIndexOf('y')+1);//
    var M = this.substring(style.indexOf('M'),style.lastIndexOf('M')+1);//
    var d = this.substring(style.indexOf('d'),style.lastIndexOf('d')+1);//
    var h = this.substring(style.indexOf('h'),style.lastIndexOf('h')+1);//
    var m = this.substring(style.indexOf('m'),style.lastIndexOf('m')+1);//
    var s = this.substring(style.indexOf('s'),style.lastIndexOf('s')+1);//
    if(s == null ||s == "" || isNaN(s)) {s = new Date().getSeconds();}
    if(m == null ||m == "" || isNaN(m)) {m = new Date().getMinutes();}
    if(h == null ||h == "" || isNaN(h)) {h = new Date().getHours();}
    if(d == null ||d == "" || isNaN(d)) {d = new Date().getDate();}
    if(M == null ||M == "" || isNaN(M)) {M = new Date().getMonth()+1;}
    if(y == null ||y == "" || isNaN(y)) {y = new Date().getFullYear();}
    var dt ;
    eval ("dt = new Date('"+ y+"', '"+(M-1)+"','"+ d+"','"+ h+"','"+ m+"','"+ s +"')");
    return dt;
}
/**//**//**//**//**//**//**//**
 * 格式化日期
 * @param   d the delimiter
 * @param   p the pattern of your date
 * @author  meizz
 */
Date.prototype.format = function(style) {
    var o = {
        "M+" : this.getMonth() + 1, //month
        "d+" : this.getDate(),      //day
        "h+" : this.getHours(),     //hour
        "m+" : this.getMinutes(),   //minute
        "s+" : this.getSeconds(),   //second
        "w+" : "天一二三四五六".charAt(this.getDay()),   //week
        "q+" : Math.floor((this.getMonth() + 3) / 3),  //quarter
        "S"  : this.getMilliseconds() //millisecond
    }
    if(/(y+)/.test(style)) {
        style = style.replace(RegExp.$1,
            (this.getFullYear() + "").substr(4 - RegExp.$1.length));
    }
    for(var k in o){
        if(new RegExp("("+ k +")").test(style)){
            style = style.replace(RegExp.$1,
                RegExp.$1.length == 1 ? o[k] :
                    ("00" + o[k]).substr(("" + o[k]).length));
        }
    }
    return style;
}
Calendar.prototype.ReturnDate = function(dt) {
    if (this.dateControl != null){this.dateControl.value = dt;}
    calendar.hide();
    if(this.dateControl.onchange == null){return;}
    //将 onchange 转成其它函数,以免触发验证事件
    var ev = this.dateControl.onchange.toString(); //找出函数的字串
    ev = ev.substring(
        ((ev.indexOf("ValidatorOnChange();")> 0) ? ev.indexOf("ValidatorOnChange();") + 20 : ev.indexOf("{") + 1)
        , ev.lastIndexOf("}"));//去除验证函数 ValidatorOnChange();
    var fun = new Function(ev);                //重新定义函数
    this.dateControl.changeEvent = fun;
    this.dateControl.changeEvent();//触发自定义 changeEvent 函数
}
 
/**//**//**//**//**//**//**//**
 * 日历类
 * @param   beginYear 1990
 * @param   endYear   2010
 * @param   lang      0(中文)|1(英语) 可自由扩充
 * @param   dateFormatStyle  "yyyy-MM-dd";
 * @version 2006-04-01
 * @author  KimSoft (jinqinghua [at] gmail.com)
 * @update
 */
function Calendar(beginYear, endYear, lang, dateFormatStyle) {
    this.beginYear = 1950;
    this.endYear = 2050;
    this.lang = 0;            //0(中文) | 1(英文)
    this.dateFormatStyle = "yyyy-MM-dd hh:mm:ss";
 
    if (beginYear != null && endYear != null){
        this.beginYear = beginYear;
        this.endYear = endYear;
    }
    if (lang != null){
        this.lang = lang
    }
 
    if (dateFormatStyle != null){
        this.dateFormatStyle = dateFormatStyle
    }
 
    this.dateControl = null;
    this.panel = this.getElementById("calendarPanel");
    this.container = this.getElementById("ContainerPanel");
    this.form  = null;
 
    this.date = new Date();
    this.year = this.date.getFullYear();
    this.month = this.date.getMonth();
 
    this.day = this.date.getDate();
    this.hour = this.date.getHours();
    this.minute = this.date.getMinutes();
    this.second = this.date.getSeconds();
 
    this.colors = {
        "cur_word"      : "#FFFFFF",  //当日日期文字颜色
        "cur_bg"        : "#EFEFEF",  //当日日期单元格背影色
        "sel_bg"        : "#FFCCCC",  //已被选择的日期单元格背影色
        "sun_word"      : "#FF0000",  //星期天文字颜色
        "sat_word"      : "#0000FF",  //星期六文字颜色
        "td_word_light" : "#333333",  //单元格文字颜色
        "td_word_dark"  : "#CCCCCC",  //单元格文字暗色
        "td_bg_out"     : "#EFEFEF",  //单元格背影色
        "td_bg_over"    : "#FFCC00",  //单元格背影色
        "tr_word"       : "#FFFFFF",  //日历头文字颜色
        "tr_bg"         : "#666666",  //日历头背影色
        "input_border"  : "#CCCCCC",  //input控件的边框颜色
        "input_bg"      : "#EFEFEF"   //input控件的背影色
    }
    /* //2008-01-29 放到了 show ,因为要做 pickMode 判断
     this.draw();
     this.bindYear();
     this.bindMonth();
     */
    //this.changeSelect();
    //this.bindData(); //2006-12-30 由民工.砖家注释
}
 
/**//**//**//**//**//**//**//**
 * 日历类属性(语言包,可自由扩展)
 */
Calendar.language = {
    "year"   : [[""], [""]],
    "months" : [["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],
        ["JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"]
    ],
    "weeks"  : [["日","一","二","三","四","五","六"],
        ["SUN","MON","TUR","WED","THU","FRI","SAT"]
    ],
    "hour"  : [["时"], ["H"]],
    "minute"  : [["分"], ["M"]],
    "second"  : [["秒"], ["S"]],
    "clear"  : [["清空"], ["CLS"]],
    "today"  : [["今天"], ["TODAY"]],
    "pickTxt"  : [["确定"], ["OK"]],//pickMode 精确到年、月时把今天变成“确定”
    "close"  : [["关闭"], ["CLOSE"]]
}
 
Calendar.prototype.draw = function() {
    calendar = this;
 
    var mvAry = [];
    //mvAry[mvAry.length]  = '  <form name="calendarForm" style="margin: 0px;">'; //因 <form> 不能嵌套
    mvAry[mvAry.length]  = '  <div name="calendarForm" style="margin: 0px;">';
    mvAry[mvAry.length]  = '    <table width="100%" border="0" cellpadding="0" cellspacing="1" style="font-size:12px;">';
    mvAry[mvAry.length]  = '      <tr>';
    mvAry[mvAry.length]  = '        <th align="left" width="10%" height="100%"><input style="border: 1px solid ' + calendar.colors["input_border"] + ';background-color:' + calendar.colors["input_bg"] + ';width:100%;height:100%;';
    if(calendar.DateMode > pickMode["month"]){mvAry[mvAry.length]  = 'display:none;';}//pickMode 精确到年时隐藏“月”
    mvAry[mvAry.length]  ='" name="prevMonth" type="button" id="prevMonth" value="<" /></th>';
    mvAry[mvAry.length]  = '        <th   width="70%" height="100%" nowrap="nowrap" ><div style="height:100%;"><select  name="calendarYear" id="calendarYear" style="width:50%;height:100%;font-size:12px;"></select><select name="calendarMonth" id="calendarMonth" style="width:50%;height:100%;font-size:12px;';
    if(calendar.DateMode > pickMode["month"]){mvAry[mvAry.length]  = 'display:none;';}//pickMode 精确到年时隐藏“月”
    mvAry[mvAry.length]  = '"></select></div></th>';
    mvAry[mvAry.length]  = '        <th align="right" width="10%" height="100%"><input style="border: 1px solid ' + calendar.colors["input_border"] + ';background-color:' + calendar.colors["input_bg"] + ';width:100%;height:100%';
    if(calendar.DateMode > pickMode["month"]){mvAry[mvAry.length]  = 'display:none;';}//pickMode 精确到年时隐藏“月”
    mvAry[mvAry.length]  ='" name="nextMonth" type="button" id="nextMonth" value=">" /></th>';
    mvAry[mvAry.length]  = '      </tr>';
    mvAry[mvAry.length]  = '    </table>';
    mvAry[mvAry.length]  = '    <table id="calendarTable" width="100%" style="border:0px solid #CCCCCC;background-color:#FFFFFF;font-size:12px;';
    if(calendar.DateMode >= pickMode["month"]){mvAry[mvAry.length]  = 'display:none;';}//pickMode 精确到年、月时隐藏“天”
    mvAry[mvAry.length]  = '" border="0" cellpadding="3" cellspacing="1">';
    mvAry[mvAry.length]  = '      <tr>';
    for(var i = 0; i < 7; i++) {
        mvAry[mvAry.length]  = '      <th style="font-weight:normal;background-color:' + calendar.colors["tr_bg"] + ';color:' + calendar.colors["tr_word"] + ';">' + Calendar.language["weeks"][this.lang][i] + '</th>';
    }
    mvAry[mvAry.length]  = '      </tr>';
    for(var i = 0; i < 6;i++){
        mvAry[mvAry.length]  = '    <tr align="center">';
        for(var j = 0; j < 7; j++) {
            if (j == 0){
                mvAry[mvAry.length]  = '  <td style="cursor:default;color:' + calendar.colors["sun_word"] + ';"></td>';
            } else if(j == 6) {
                mvAry[mvAry.length]  = '  <td style="cursor:default;color:' + calendar.colors["sat_word"] + ';"></td>';
            } else {
                mvAry[mvAry.length]  = '  <td style="cursor:default;"></td>';
            }
        }
        mvAry[mvAry.length]  = '    </tr>';
    }
 
//2009-03-03 添加的代码,放置时间的行
    mvAry[mvAry.length]  = '      <tr style="';
    if(calendar.DateMode >= pickMode["day"]){mvAry[mvAry.length]  = 'display:none;';}//pickMode 精确到时日隐藏“时间”
    mvAry[mvAry.length]  = '"><td align="center" colspan="7">';
    mvAry[mvAry.length]  = '      <select name="calendarHour" id="calendarHour" style="width:25%;font-size:12px;"></select>' + Calendar.language["hour"][this.lang];
    mvAry[mvAry.length]  = '<span style="'
    if(calendar.DateMode >= pickMode["hour"]){mvAry[mvAry.length]  = 'display:none;';}//pickMode 精确到小时时隐藏“分”
    mvAry[mvAry.length]  = '"><select name="calendarMinute" id="calendarMinute" style="width:25%;font-size:12px;"></select>' + Calendar.language["minute"][this.lang]+'</span>';
    mvAry[mvAry.length]  = '<span style="'
    if(calendar.DateMode >= pickMode["minute"]){mvAry[mvAry.length]  = 'display:none;';}//pickMode 精确到小时、分时隐藏“秒”
    mvAry[mvAry.length]  = '"><select name="calendarSecond" id="calendarSecond" style="width:25%;font-size:12px;"></select>'+ Calendar.language["second"][this.lang]+'</span>';
    mvAry[mvAry.length]  = '      </td></tr>';
 
    mvAry[mvAry.length]  = '    </table>';
    //mvAry[mvAry.length]  = '  </from>';
    mvAry[mvAry.length]  = '      <div align="center" style="padding:4px 4px 4px 4px;background-color:' + calendar.colors["input_bg"] + ';">';
 
    mvAry[mvAry.length]  = '        <input name="calendarToday" class="btn" style="width:60px;" type="button" id="calendarToday" value="'
    mvAry[mvAry.length]  = (calendar.DateMode == pickMode["day"]) ? Calendar.language["today"][this.lang] : Calendar.language["pickTxt"][this.lang];
    mvAry[mvAry.length]  = '" style="border: 1px solid ' + calendar.colors["input_border"] + ';background-color:' + calendar.colors["input_bg"] + ';width:60px;height:20px;font-size:12px;cursor:pointer"/>';
 
     mvAry[mvAry.length]  ='<br/>'
 
        mvAry[mvAry.length]  = '      </div>';
 
    mvAry[mvAry.length]  = '  </div>';
    this.panel.innerHTML = mvAry.join("");
 
    var obj = this.getElementById("prevMonth");
    obj.onclick = function () {calendar.goPrevMonth(calendar);}
    obj.onblur = function () {calendar.onblur();}
    this.prevMonth= obj;
 
    obj = this.getElementById("nextMonth");
    obj.onclick = function () {calendar.goNextMonth(calendar);}
    obj.onblur = function () {calendar.onblur();}
    this.nextMonth= obj;
 
 
 
 
 
 
 
 
    obj = this.getElementById("calendarYear");
    obj.onchange = function () {calendar.update(calendar);}
    obj.onblur = function () {calendar.onblur();}
    this.calendarYear = obj;
 
    obj = this.getElementById("calendarMonth");
    with(obj)
    {
        onchange = function () {calendar.update(calendar);}
        onblur = function () {calendar.onblur();}
    }this.calendarMonth = obj;
 
    obj = this.getElementById("calendarHour");
    obj.onchange = function () {calendar.hour = this.options[this.selectedIndex].value;}
    obj.onblur = function () {calendar.onblur();}
    this.calendarHour = obj;
 
    obj = this.getElementById("calendarMinute");
    obj.onchange = function () {calendar.minute = this.options[this.selectedIndex].value;}
    obj.onblur = function () {calendar.onblur();}
    this.calendarMinute = obj;
 
    obj = this.getElementById("calendarSecond");
    obj.onchange = function () {calendar.second = this.options[this.selectedIndex].value;}
    obj.onblur = function () {calendar.onblur();}
    this.calendarSecond = obj;
 
    obj = this.getElementById("calendarToday");
    obj.onclick = function () {
        var today = (calendar.DateMode != pickMode["day"]) ?
            new Date(calendar.year,calendar.month,calendar.day,calendar.hour,calendar.minute,calendar.second)
            : new Date();//2008-01-29
        calendar.ReturnDate(today.format(calendar.dateFormatStyle));
    }
    this.calendarToday = obj;
}
 
//年份下拉框绑定数据
Calendar.prototype.bindYear = function() {
    var cy = this.calendarYear;
    cy.length = 0;
    for (var i = this.beginYear; i <= this.endYear; i++){
        cy.options[cy.length] = new Option(i + Calendar.language["year"][this.lang], i);
    }
}
//月份下拉框绑定数据
Calendar.prototype.bindMonth = function() {
    var cm = this.calendarMonth;
    cm.length = 0;
    for (var i = 0; i < 12; i++){
        cm.options[cm.length] = new Option(Calendar.language["months"][this.lang][i], i);
    }
}
//小时下拉框绑定数据
Calendar.prototype.bindHour = function() {
    var ch = this.calendarHour;
    if(ch.length > 0){return;}//2009-03-03 不需要重新绑定,提高性能
    //ch.length = 0;
    var h;
    for (var i = 0; i < 24; i++){
        h = ("00" + i +"").substr(("" + i).length);
        ch.options[ch.length] = new Option(h, h);
    }
}
//分钟下拉框绑定数据
Calendar.prototype.bindMinute = function() {
    var cM = this.calendarMinute;
    if(cM.length > 0){return;}//2009-03-03 不需要重新绑定,提高性能
    //cM.length = 0;
    var M;
    for (var i = 0; i < 60; i++){
        M = ("00" + i +"").substr(("" + i).length);
        cM.options[cM.length] = new Option(M, M);
    }
}
//秒钟下拉框绑定数据
Calendar.prototype.bindSecond = function() {
    var cs = this.calendarSecond;
    if(cs.length > 0){return;}//2009-03-03 不需要重新绑定,提高性能
    //cs.length = 0;
    var s;
    for (var i = 0; i < 60; i++){
        s = ("00" + i +"").substr(("" + i).length);
        cs.options[cs.length] = new Option(s, s);
    }
}
//向前一月
Calendar.prototype.goPrevMonth = function(e){
    if (this.year == this.beginYear && this.month == 0){return;}
    this.month--;
    if (this.month == -1) {
        this.year--;
        this.month = 11;
    }
    this.date = new Date(this.year, this.month, 1);
    this.changeSelect();
    this.bindData();
}
//向后一月
Calendar.prototype.goNextMonth = function(e){
    if (this.year == this.endYear && this.month == 11){return;}
    this.month++;
    if (this.month == 12) {
        this.year++;
        this.month = 0;
    }
    this.date = new Date(this.year, this.month, 1);
    this.changeSelect();
    this.bindData();
}
//改变SELECT选中状态
Calendar.prototype.changeSelect = function() {
    var cy = this.calendarYear;
    var cm = this.calendarMonth;
    var ch = this.calendarHour;
    var cM = this.calendarMinute;
    var cs = this.calendarSecond;
//2006-12-30 由民工.砖家修改,减少运算次数
    cy[this.date.getFullYear()-this.beginYear].selected = true;
    cm[this.date.getMonth()].selected =true;
//2009-03-03 添加,初始化时间的值
    ch[this.hour].selected =true;
    cM[this.minute].selected =true;
    cs[this.second].selected =true;
}
//更新年、月
Calendar.prototype.update = function (e){
    this.year  = e.calendarYear.options[e.calendarYear.selectedIndex].value;
    this.month = e.calendarMonth.options[e.calendarMonth.selectedIndex].value;
    this.date = new Date(this.year, this.month, 1);
    //this.changeSelect();
    this.bindData();
}
//绑定数据到月视图
Calendar.prototype.bindData = function () {
    var calendar = this;
    if(calendar.DateMode >= pickMode["month"]){return;}//2008-01-29
// var dateArray = this.getMonthViewArray(this.date.getYear(), this.date.getMonth());
    //2006-12-30 由民工.砖家修改 在Firefox 下年份错误
    var dateArray = this.getMonthViewArray(this.date.getFullYear(), this.date.getMonth());
    var tds = this.getElementById("calendarTable").getElementsByTagName("td");
    for(var i = 0; i < tds.length; i++) {
        tds[i].style.backgroundColor = calendar.colors["td_bg_out"];
        tds[i].onclick = function () {return;}
        tds[i].onmouseover = function () {return;}
        tds[i].onmouseout = function () {return;}
        if (i > dateArray.length - 1) break;
        tds[i].innerHTML = dateArray[i];
        if (dateArray[i] != ""){
            tds[i].bgColorTxt = "td_bg_out"; //2009-03-03 保存背景色的class
            var cur = new Date();
            tds[i].isToday = false;
            if (cur.getFullYear() == calendar.date.getFullYear() && cur.getMonth() == calendar.date.getMonth() && cur.getDate() == dateArray[i]) {
                //是今天的单元格
                tds[i].style.backgroundColor = calendar.colors["cur_bg"];
                tds[i].bgColorTxt = "cur_bg";
                tds[i].isToday = true;
            }
            if(calendar.dateControl != null )
            {
                cur = calendar.dateControl.value.toDate(calendar.dateFormatStyle);
                if (cur.getFullYear() == calendar.date.getFullYear() && cur.getMonth() == calendar.date.getMonth()&& cur.getDate() == dateArray[i]) {
                    //是已被选中的单元格
                    calendar.selectedDayTD = tds[i];
                    tds[i].style.backgroundColor = calendar.colors["sel_bg"];
                    tds[i].bgColorTxt = "sel_bg";
                }
            }
            tds[i].onclick = function () {
                if(calendar.DateMode == pickMode["day"]) //2009-03-03 当选择日期时,点击格子即返回值
                {
                    calendar.ReturnDate(new Date(calendar.date.getFullYear(),
                        calendar.date.getMonth(),
                        this.innerHTML).format(calendar.dateFormatStyle));
                }
                else
                {
                    if(calendar.selectedDayTD != null) //2009-03-03 清除已选中的背景色
                    {
                        calendar.selectedDayTD.style.backgroundColor =(calendar.selectedDayTD.isToday)? calendar.colors["cur_bg"] : calendar.colors["td_bg_out"];
                    }
                    this.style.backgroundColor = calendar.colors["sel_bg"];
                    calendar.day = this.innerHTML;
                    calendar.selectedDayTD = this; //2009-03-03 记录已选中的日子
                }
            }
            tds[i].style.cursor ="pointer";
            tds[i].onmouseover = function () {
                this.style.backgroundColor = calendar.colors["td_bg_over"];
            }
            tds[i].onmouseout = function () {
                if(calendar.selectedDayTD != this) {
                    this.style.backgroundColor = calendar.colors[this.bgColorTxt];}
            }
            tds[i].onblur = function () {calendar.onblur();}
        }
    }
}
 
//根据年、月得到月视图数据(数组形式)
Calendar.prototype.getMonthViewArray = function (y, m) {
    var mvArray = [];
    var dayOfFirstDay = new Date(y, m, 1).getDay();
    var daysOfMonth = new Date(y, m + 1, 0).getDate();
    for (var i = 0; i < 42; i++) {
        mvArray[i] = "";
    }
    for (var i = 0; i < daysOfMonth; i++){
        mvArray[i + dayOfFirstDay] = i + 1;
    }
    return mvArray;
}
//扩展 document.getElementById(id) 多浏览器兼容性 from meizz tree source
Calendar.prototype.getElementById = function(id){
    if (typeof(id) != "string" || id == "") return null;
    if (document.getElementById) return document.getElementById(id);
    if (document.all) return document.all(id);
    try {return eval(id);} catch(e){ return null;}
}
//扩展 object.getElementsByTagName(tagName)
Calendar.prototype.getElementsByTagName = function(object, tagName){
    if (document.getElementsByTagName) return document.getElementsByTagName(tagName);
    if (document.all) return document.all.tags(tagName);
}
//取得HTML控件绝对位置
Calendar.prototype.getAbsPoint = function (e){
    var x = e.offsetLeft;
    var y = e.offsetTop;
    while(e = e.offsetParent){
        x += e.offsetLeft;
        y += e.offsetTop;
    }
    return {"x": x, "y": y};
}
//显示日历
Calendar.prototype.show = function (dateObj, popControl) {
    if (dateObj == null){
        throw new Error("arguments[0] is necessary")
    }
    this.dateControl = dateObj;
    var now =  new Date();
    this.date = (dateObj.value.length > 0) ? new Date(dateObj.value.toDate(this.dateFormatStyle)) : now.format(this.dateFormatStyle).toDate(this.dateFormatStyle) ;//若为空则根据dateFormatStyle初始化日期
 
    if(this.panel.innerHTML==""||cal.dateFormatStyleOld != cal.dateFormatStyle)//2008-01-29 把构造表格放在此处,2009-03-03 若请示的样式改变,则重新初始化
    {
        this.draw();
        this.bindYear();
        this.bindMonth();
        this.bindHour();
        this.bindMinute();
        this.bindSecond();
    }
    this.year = this.date.getFullYear();
    this.month = this.date.getMonth();
    this.day = this.date.getDate();
    this.hour = this.date.getHours();
    this.minute = this.date.getMinutes();
    this.second = this.date.getSeconds();
    this.changeSelect();
    this.bindData();
 
    if (popControl == null){
        popControl = dateObj;
    }
    var xy = this.getAbsPoint(popControl);
    //this.panel.style.left = xy.x + "px";
    //this.panel.style.top = (xy.y + dateObj.offsetHeight) + "px";
    this.panel.style.left = (xy.x + leftX)+ "px"; // 加入自定义偏移量
    this.panel.style.top = (xy.y + topY + dateObj.offsetHeight) + "px";
 
    //把 visibility 变为 display,并添加失去焦点的事件  //this.setDisplayStyle("select", "hidden");
    //this.panel.style.visibility = "visible";
    //this.container.style.visibility = "visible";
    this.panel.style.display = "";
    this.container.style.display = "";
 
    if( !this.dateControl.isTransEvent)
    {
        this.dateControl.isTransEvent = true;
        /* 已写在返回值的时候  ReturnDate 函数中,去除验证事件的函数
         this.dateControl.changeEvent = this.dateControl.onchange;//将 onchange 转成其它函数,以免触发验证事件
         this.dateControl.onchange = function()
         {if(typeof(this.changeEvent) =='function'){this.changeEvent();}}*/
        if(this.dateControl.onblur != null){
            this.dateControl.blurEvent = this.dateControl.onblur;}//2007-09-14 保存主文本框的 onblur ,使其原本的事件不被覆盖
        this.dateControl.onblur = function()
        {calendar.onblur();if(typeof(this.blurEvent) =='function'){this.blurEvent();}
        }
    }
 
    this.container.onmouseover = function(){isFocus=true;}
    this.container.onmouseout = function(){isFocus=false;}
}
 
//隐藏日历
Calendar.prototype.hide = function() {
    //this.setDisplayStyle("select", "visible");
    //this.panel.style.visibility = "hidden";
    //this.container.style.visibility = "hidden";
    this.panel.style.display = "none";
    this.container.style.display = "none";
    isFocus=false;
}
 
//焦点转移时隐藏日历
Calendar.prototype.onblur = function() {
    if(!isFocus){this.hide();}
}
 
//确保日历容器节点在 body 最后,否则 FireFox 中不能出现在最上方
function InitContainerPanel() //初始化容器
{
    var str = '<div id="calendarPanel" style="position: absolute;display: none;z-index:9999; background-color: #FFFFFF;border: 1px solid #CCCCCC;font-size:12px;"></div>';
    if(document.all)
    {
        str += '<iframe style="position:absolute;z-index:2000;width:expression(this.previousSibling.offsetWidth);';
        str += 'height:expression(this.previousSibling.offsetHeight);';
        str += 'left:expression(this.previousSibling.offsetLeft);top:expression(this.previousSibling.offsetTop);';
        str += 'display:expression(this.previousSibling.style.display);" scrolling="no" frameborder="no"></iframe>';
    }
    var div = document.createElement("div");
    div.innerHTML = str;
    div.id = "ContainerPanel";
    div.style.display ="none";
    document.body.appendChild(div);
}//调用calendar.show(dateControl, popControl);
View Code
复制代码

index.html

复制代码
<!DOCTYPE html>
<html>
    <head>
        <title>时间控件</title>
         <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <script src="./js/src/datePlugin.js"></script>
    </head>
   <body>
        <input onclick="SelectDate(this,'yyyy-MM-dd hh:mm:ss')" readonly="true"  type="text" id="date">
   </body>
</html>
复制代码

 

#js去掉readonly属性
js01 = "document.getElementById('date').removeAttribute('readonly');"
driver.execute_script(js01)

#再输入值
js02 = "document.getElementById('date').value='2018-09-13';"
driver.execute_script(js02)

 

 5、js对下拉框隐藏属性的选择

参考文章:《Selenium操作隐藏的元素》、《python+selenium select下拉选择框定位处理

Select.html

复制代码
<!DOCTYPE html>
<html>
    <head>
        <title>隐藏元素定位</title>
    </head>
    <body>
        <div id="div01">
            <div id="div01_01">
                <div id="div01_01_01">
                    <select name="sel01" style="display: none;">
                        <option value="aa">AA</option>
                        <option value="bb">BB</option>
                        <option value="cc">CC</option>
                        <option value="dd">DD</option>
                    </select>
                </div>
            </div>
        </div>
        <div id="div02" class="select_cls02">
            <div id="div02_01">
                <div id="div01_02_01">
                    <select name="sel02" style="display: none;">
                        <option value="ee">EE</option>
                        <option value="ff">FF</option>
                        <option value="gg">GG</option>
                        <option value="hh">HH</option>
                    </select>
                </div>
            </div>    
        </div>
    </body>
</html>
复制代码

 

代码如下:

复制代码
#把隐藏的属性改为可见,引号一定要加上,'block'
js = "document.querySelectorAll('select')[1].style.display='block';"
driver.execute_script(js)

#定位有以下几种#
sel = driver.find_element(By.CSS_SELECTOR,"div#div02 div#div02_01 div select")
②#
sel = driver.find_element(By.CSS_SELECTOR,"div#div02 > div#div02_01 > div > select")
③#
sel = driver.find_element(By.CSS_SELECTOR,"#div02 div div select")
④#div:nth-child(1)意思为div标签下还有一个子div,相当于#div02 div(父) div(子) select
sel = driver.find_element(By.CSS_SELECTOR,"#div02 div:nth-child(1) select")
⑤#*[name=sel02]或[name=sel02]或select[name=sel02]
sel = driver.find_element(By.CSS_SELECTOR,"*[name=sel02]")
⑥#
sel = driver.find_element(By.XPATH,"//div[@id='div02']/div/div/select")
⑦#
sel = driver.find_element(By.XPATH,"//*[@id='div02']/div/div/select")
⑧#引号一定加上,@id='div02' and @class='select_cls02'
sel = driver.find_element(By.XPATH,"//div[@id='div02' and @class='select_cls02']/div/div/select")

#下拉框选择值
Select(sel).select_by_value('hh')
复制代码

 

6、js选择复选框或取消、全选

html代码:

参考:《html复选框的全选和全不选

复制代码
<!DOCTYPE html>
<html>
    <head>
        <script>
            function checkAll(){
                //1.获取编号前面的复选框
                var checkAllEle = document.getElementById("checkAll");
                //2.对编号前面复选框的状态进行判断
                if(checkAllEle.checked==true){
                    //3.获取下面所有的复选框
                    var checkOnes = document.getElementsByName("checkOne");
                    //4.对获取的所有复选框进行遍历
                    for(var i=0;i<checkOnes.length;i++){
                        //5.拿到每一个复选框,并将其状态置为选中
                        checkOnes[i].checked=true;
                    }
                }else{
                    //6.获取下面所有的复选框
                    var checkOnes = document.getElementsByName("checkOne");
                    //7.对获取的所有复选框进行遍历
                    for(var i=0;i<checkOnes.length;i++){
                        //8.拿到每一个复选框,并将其状态置为未选中
                        checkOnes[i].checked=false;
                    }
                }
            }
        </script>
    </head>
    <body>
        <table>
            <thead>
                <tr>
                    <th colspan="2">
                        <input type="checkbox" id="checkAll" onclick="checkAll()"/>
                    </th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td><input type="checkbox" name="checkOne"></td>
                    <td>xx1</td>
                </tr>
                <tr>
                    <td><input type="checkbox" name="checkOne"></td>
                    <td>xx2</td>
                </tr>
                <tr>
                    <td><input type="checkbox" name="checkOne"></td>
                    <td>xx3</td>
                </tr>
                <tr>
                    <td><input type="checkbox" name="checkOne"></td>
                    <td>xx4</td>
                </tr>
            </tbody>
        </table>
    </body>
</html>
View Code
复制代码

Python代码:

复制代码
driver = webdriver.Chrome()
driver.maximize_window()
driver.get("file:///Users/xxx/Desktop/JavaScript/checkbox.html")

#通过执行js,选中复选框
driver.execute_script('var chk =document.getElementById("checkAll"); chk.checked="checked"')
print (driver.find_element_by_id("checkAll").is_selected())
sleep(3)
#通过执行js,取消选中复选框
driver.execute_script('var chk =document.getElementById("checkAll"); chk.checked=""')
print (driver.find_element_by_id("checkAll").is_selected())
sleep(3)
#通过执行js,全选所有复选框,执行的js可以定义函数,通过调用函数全选
driver.execute_script('var checkboxs=document.getElementsByTagName("input");\
for (var i=0;i<checkboxs.length;i++) \
{    var e=checkboxs[i];\
if(e.type=="checkbox")\
{e.checked="checked"; \
} \
};')
sleep(3)
复制代码

 

复选框定位还可以参考:《Selenium2+python自动化65-js定位几种方法总结【转载】

# 勾选记住密码
js4 = 'document.getElementsByName("remember_me")[0].click();'
driver.execute_script(js4)

 

7、针对display='none',但是标签中没有id属性

代码如下:

js = "document.querySelector('#xtgl > div > span').style.display='block';"
driver.execute_script(js)
text = driver.find_element(By.CSS_SELECTOR,"#xtgl > div > span").text

参考:

python+selenium:解决上传文件<input type='file'>标签属性被css的visibility隐藏导致无法定位元素的问题

selenium:解决页面元素display:none的方法

=========================================

扩展:还有其他的js定位,请参考

1、感谢:Selenium Webdriver常用JS操作

2、感谢:python之selenium调用js(execute_script)

 

posted @   Owen_ET  阅读(5030)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
  1. 1 イエスタデイ(翻自 Official髭男dism) 茶泡饭,春茶,kobasolo
  2. 2 模様 (TV size ver.) Ivy to Fraudulent Game
  3. 3 河口恭吾
  4. 4 愛してる 高鈴
  5. 5 一生所爱 卢冠廷,莫文蔚
  6. 6 世间美好与你环环相扣 柏松
  7. 7 理想三旬 陈鸿宇
  8. 8 不浪漫罪名 王杰
  9. 9 樱花树下 张敬轩
  10. 10 因为你在 达闻西乐队,福禄寿FloruitShow
  11. 11 悬溺 葛东琪
樱花树下 - 张敬轩
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

作词 : 林若宁

作曲 : 伍卓贤

树荫有一只蝉 跌落你身边

惊慌到失足向前

然后扑入我一双肩

令你腼腆一脸 像樱花万千

怀念美好高中两年

期望你的青春不变

去到今天

还记得樱花正开

还未懂跟你示爱

初春来时彼此约定过 继续期待

人置身这大时代

投入几番竞技赛

曾分开曾相爱

等待花蕊又跌下来

才洞悉这是恋爱

未有过的爱情 但有种温馨

未有过的爱情 但有种温馨

归家那单车小径

沿路细听你的歌声

没法再三倾听 你的感动昵称

维系错的一番友情

无奈已经不可纠正

太过坚贞

还记得樱花正开

还未懂跟你示爱

初春来时彼此闭着眼 渴望未来

人置身这大时代

投入几番竞技赛

曾分开曾相爱

等待跟你未爱的爱

你说悲不悲哀

秒速之间变改 小小世界

眷恋也许走不过 拆卸的街

少女亦随年渐长 走得多么快

如有天樱花再开

如有天樱花再开

期望可跟你示爱

当天园林 今天已换上满地青苔

如有天置地门外

乘电车跨过大海

匆匆跟你相望一眼 没理睬

明日花 昨日已开

点击右上角即可分享
微信分享提示