最新消息:这里是最新消息

selenium将find_element_by_XXX简写byxx函数

python benty 289浏览 0评论

为了写自动化脚本,但是selenium的查找元素名字太长了,以至于效率上不去

比如说,能不能将browser.find_element_by_id()函数直接简化写成byid()这样的函数呢,答案是可以,自己用了两种方法来实现,由于对python水平认知有限,如果写的不到位还请多多指点.

第一种方法是自己写一个类库Bsl和一个方法chrome.方法用来打开浏览器(chrome和ie)并返回浏览器对象.把浏览器对象传入我们的类库,就可以直接改写我们想要的功能函数,但是有个缺点就是需要每次操作将对象指针初始化,因为操作一次,对象的指针就移动到定位的元素了,不过好处就是不用在重新查找元素,当前元素直接点击就可以.直接上代码

#encoding=utf-8
”’
#
# @description 封装一个selenium类
# @author benty 2021-04-13 17:51:06
# @param
# @return
#
”’
from selenium import webdriver
from time import sleep
import os
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
# from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
import time
from selenium.webdriver.common.keys import Keys
# DesiredCapabilities.INTERNETEXPLORER[‘ignoreProtectedModeSettings’] = True
def chrome(url=””,type=”chrome”,t=15):
    ”’初始化浏览器并打开”’
    if type==”chrome”:
        options = webdriver.ChromeOptions()
        options.add_argument(‘–log-level=3’)
        options.add_experimental_option(‘excludeSwitches’,[‘enable-logging’])
        options.add_argument(‘disable-infobars’)
        # options.add_argument(‘headless’)#静默模式
        b=webdriver.Chrome(options=options,service_log_path=os.devnull,desired_capabilities = None)
    else:#不是chrome就是IE
        path = r’D:\work\python\自动化\清华控股\tools\IEDriverServermabt.exe’
        b = webdriver.Ie(executable_path=path)
        sleep(1)
    b.implicitly_wait(t)
    b.get(url)
    # WebDriverWait(self.b, 10).until(lambda x: self.b.find_element_by_link_text(‘hao123’))#显式等待
    # print(‘=========================================================’)
    b.maximize_window()  # 放大页面
    return b
class Bsl():
    ”’封装浏览器的查找元素功能”’
    def __init__(self,obj={}):
        ”’初始化浏览器并打开”’
        self.b=obj
        self.init=obj
    #测试学习
    #下面都是获取一个结果
    def byid2(self,elem):
        ”’获取id,直接写名字不用加#”’
        pass
        # return self.b.find_element_by_id
        # return self
    #下面都是获取一个结果
    def byid(self,elem):
        ”’获取id,直接写名字不用加#”’
        self.b=self.b.find_element_by_id(elem)
        return self
    def byclass(self,elem):
        ”’必须获取class元素的第一个元素”’
        self.b=self.b.find_element_by_class_name(elem)
        return self
    def byname(self,elem):
        ”’必须获取标签的第一个name属性元素”’
        self.b=self.b.find_element_by_name(elem)
        return self
    def byxpath(self,elem):
        ”’必须根据xpath找到第一个元素”’
        self.b=self.b.find_element_by_xpath(elem)
        return self
    def bytagname(self,elem):
        ”’必须获取一个html标签”’
        self.b=self.b.find_element_by_tag_name(elem)
        return self
    def bycss(self,css):
        ”’必须根据css选择器找到一个元素”’
        self.b=self.b.find_element_by_css_selector(css)
        return self
    #下面都是获取多个结果返回列表
    def byclasses(self,elem):
        ”’获取class元素并返回一个列表”’
        self.b=self.b.find_elements_by_class_name(elem)
        return self
    def bynames(self,elem):
        ”’获取标签的name属性返回一个列表”’
        self.b=self.b.find_elements_by_name(elem)
        return self
    def byxpaths(self,elem):
        ”’根据xpath获取一个列表”’
        self.b=self.b.find_elements_by_xpath(elem)
        return self
    def bytagnames(self,elem):
        ”’获取html标签列表”’
        self.b=self.b.find_elements_by_tag_name(elem)
        return self
    def bycsss(self,css):
        ”’根据css返回一个元素列表”’
        self.b=self.b.find_elements_by_css_selector(css)
        return self
    #封装其他功能
    def title99(self):
        self.b=self.b.title
    def attr(self,attrk):
        ”’封装get_attribute()”’
        tmp=self.b.get_attribute(attrk)
        self.b=self.init
        return tmp
    def atext(self,txt):
        ”’根据标签文本找元素”’
        self.b=self.b.find_element_by_link_text(txt)
        return self
    @property
    def text(self):
        ”’返回属性并初始化对象”’
        tmp=self.b.text
        self.b=self.init
        return tmp
    def toframe(self,name):
        ”’切换到其他frame页面找内容”’
        self.b.switch_to.frame(name)
        return self
    def todefault(self):
        ”’切换到默认frame,不需要返回”’
        self.b.switch_to.default_content()
        return self
    def runjs(self,str):
        ”’执行js代码”’
        self.init.execute_script(str)
        # return self
    def wait(self,time=10):
        ”’等待elem元素出现”’
        return WebDriverWait(self.b,time)
    def pagewait(self,keywords,textobj,waittime=15):
        ”’判断关键词keywords是否在textobj,不在一直等,存在返回1,主要对ajax页面进行分析”’
        ppagestat=0
        timek=0
        while ppagestat==0:
            if keywords in textobj:
                ppagestat=1
            else:
                print(“else等待元素出现”)
                time.sleep(0.5)
                timek+=1
                if timek>waittime*2:
                    #默认最大等待时间30s,超时跳出
                    break
        return ppagestat
    @property
    def out(self):
        ”’返回操作对象指针,可调用find_element_XXX”’
        return self.b
    @property
    def outin(self):
        ”’返回self对象自身,可重新链式调用类方法”’
        return self
    @property
    def ini(self):
        ”’重置类对象指针,初始化浏览器对象”’
        self.b=self.init
        return self
    #结束浏览器进程
    def close(self):
        ”’关闭浏览器”’
        self.b.quit()
        # self.b.file_detector_context
if __name__ == ‘__main__’:
    #在当前文件执行
    ”’
    目前b是原始的对象,可以访问find_element_by_id之类的原始函数
    bk是封装好的对象,可以访问自己定义的方法,也可以链式.不过访问一次指针就变化一次,访问attr/text可以重置,访问其他函数指针就变了,可以调用属性.ini重置指针
    ini是初始化对象,out是转换成原始的可点击操作的对象,IE要用32位的系统,不然输入会卡顿,点击无效
    不完美但是可以链式调用!!!!
    知识点:chrome点击li标签(里面有a链接)可以跳转,但是ie环境确不能跳转,ie需要点击a
    ”’
    # b=Brower(“https://www.thepaper.cn/searchResult.jsp”,”IE”)
    starttime=time.perf_counter()
    # b=chrome(‘https://www.w3school.com.cn/’,t=5)
    b=chrome(‘https://www.runoob.com/try/try.php?filename=tryhtml_basic_link’,t=5)
    bk=Bsl(b)
    ”’这里采用原生的方法试试”’
    # print(b.title)
    # print(b)
    # b.find_element_by_id(“navsecond”).find_elements_by_link_text(“HTML”)[0].click()
    # b.byid(“intro”).byatexts(“现在开始学习 HTML”)[0].click()
    # b.toframe(“iframeResult”)
    # b.bytagname(“a”).click()
    # b.switch_to_window()
    # b.byclasses(“item-top”)[3].click()
    # b.quit()
    # b.find_element_by_id(“intro”).find_element_by_link_text(“现在开始学习 HTML”).click()
    # print(b)
    # b.find_element_by_id(“tpn”).find_element_by_class_name(“next”).find_element_by_tag_name(“a”).click()
    # b.find_element_by_link_text(“HTML 计算机代码”).click()
    # b.find_element_by_link_text(“HTML 注释”).click()
    # end
    # print(bk)
    # print(b.title)
    # print(bk.pagewait(“百度”,b.title,waittime=2))
    # print(bk.byid(“s-top-left”).find_element_by_link_text(“地图”).get_attribute(“outerHTML”))
    # x=b.get_window_position()
    ”’ ”’
    # print(b.title)
    # bk.todefault()
    # bk.toframe(“iframeResult”).bytagname(“body”).bytagname(“a”).out.click()
    # x=bk.ini.byclasses(“item-top”).out
    # print(x)
    print(“程序一共耗时:{}秒”.format(time.perf_counter()-starttime))
    # print(bk)
    #链式调用查找元素
    # s=bk.byid(“navsecond”).bytagname(‘ul’).atext(‘CSS’).text
    # print(s)
    #上一步有了text属性指针已经重置,下一个移动指针
    # bk.byid(“navsecond”)
    # x=8
    #上一个移动指针了,如果想要调用方法查找属性必须ini初始化对象指针
    # x=bk.ini.byid(“x”).out
    #.out属性是将对象return self.b转换为可调用原生find_element方法的指针
    # y=b.find_element_by_id(“x”)
    # print(y)
    # js=’document.getElementById(“h”).click();’
    # bk.runjs(js)
    # bk.ini.byid(“navsecond”).bytagname(‘ul’).bytagname(‘li’).out.send_keys(Keys.ENTER)
    # bk.ini.atext(‘现在开始学习 HTML’).out.click()
    # y=b.find_element_by_id(“navsecond”).find_element_by_tag_name(‘ul’).find_element_by_tag_name(‘a’).click()
    # x.click()
    # print(y)
    # y.click()
    # print(x)
    #重置指针并查找元素,转换原生对象进行点击.此时对象指针还停留在id元素上,只是指针是self.b不能调用类方法
    # bk.ini.byid(“searched_content”).out.click()
    #上一步用了out现在的指针已经是指向self.b而不是self自身了,不能链式调用了
    #此时的指针在输入框所以不用重新查找元素直接out转换为原生对象发送文字即可
    # bk.out.send_keys(“php”) #用out是为了调原生的方法
    #定位发送按钮(最后一个-1 input元素)
    # j=bk.ini.byid(“searchform”).bytagnames(“input”).out[-1]
    #click()方法返回none
    # j.click()
    # sleep(1)
    # exit()
    # b.byid(“kw”).send_keys(“keysdkfjk”)
    # b.byid(‘su’).click()
    # sleep(5)
    # x=b.bytagname(‘h3’).text
    # print(x)
    # b.runjs(‘window.scrollTo(0,document.body.scrollHeight)’)
    # print(b.title)
    # b.close()
    #默认查找元素是等网页全部加载完毕再进行往下执行,ajax不行,一定要sleep等待
    # sleep(5)
    # ok=b.byxpath(“//div[@class=’focus’]//img[@alt=’对称加密和非对称加密’]”).get_attribute(“src”)
    # print(ok)
    # #这里图片是ajax,如要等待5s
    # sleep(5)
    # ok=b.byxpath(“//div[@class=’focus’]//img[@alt=’对称加密和非对称加密’]”).get_attribute(“src”)
    # print(ok)
    # print(b.byclass(‘sc_inp’).get_attribute(‘name’))
    # print(b.byid(‘sc_inp’).is_displayed())#input元素当然不可见了
    # print(b.byid(‘sc_inp’).is_enabled())
    # b.wait().until(lambda x:b.byclass(‘sc_inp’).is_displayed())
    # print(b.title())
    # b.close()
    # print(b.bytagname(‘title’).text)
    # b.byclasses(“sc_inp”)[0].click()
    # b.byclass(“sc_inp”).send_keys(‘洛阳’)
    # sleep(4)
    # b.byid(‘searchResultForm’).byclasses(‘sc_bt’)[0].click()
    # # b.byclasses(‘sc_bt’)[0].click()
    # print(b.byclass(‘sc_bt’).is_enabled())
    # # b.wait().until(lambda x:b.byclass(“sc_bt”).click())
    # # b.runjs(‘window.scrollTo(0,document.body.scrollHeight)’)
    # try:
    #     ok=b.wait(3).until(lambda brower:b.atext(“上海书评”))
    #     print(ok)
    # except:
    #     b.runjs(‘window.scrollTo(0,document.body.scrollHeight+50)’)
    # print(“找到元素停止了.”)
”’标记常用的用语
browser.execute_script(‘window.scrollTo(0,document.body.scrollHeight)’)#下翻到页低
WebDriverWait(browser,10).until(lambda browser:browser.find_element_by_id(“kw”)).send_keys(“pytest”)
获取属性get-attribute 获取文本.text    点击.click()    发送文本.send_keys(xx)
尽量先试用id/class/name等方式进行定位,实在不行再用xpath,xpath有延时
find_element_by_class_name 找class只找第一个,找不到报错
find_elements_by_class_name  找class返回所有的列表,找不到为空
”’

按照上面就可以简写selenium函数并且可以支持链式调用

 

 

 

转载请注明:稻香的博客 » selenium将find_element_by_XXX简写byxx函数

发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址