zoukankan      html  css  js  c++  java
  • selenium使用总结

    selenium

    selenium是一个支持各大浏览器的自动化测试工具,包括 Chrome,Safari,Firefox ,ie等。再构造爬虫时,如果我们加入了User-Agent,那么变伪装成了浏览器,可以骗过一些技术水平不太高的网站。但如果使用selenium,则就不是伪装浏览器,而是真正的用浏览器去访问。有时我们可能会遇到这种情况,前端页面展示出来的东西,并不在后端源代码中,自然无法通过使用requests请求获得源码进行爬取。这时候就可以使用selenium进行爬取数据,因为他就是用真实的浏览器去访问页面的,所以出现的内容和我们在前端看到的是一模一样的。

    0x01:selenium安装

    python下使用pip安装

    pip install selenium
    

    此外,因为selenium是配合浏览器一起使用,所以需要下载浏览器的驱动(webdriver),以chrome为例
    chrome的webdriver: http://chromedriver.storage.googleapis.com/index.html
    不同的Chrome的版本对应的chromedriver.exe 版本也不一样,下载时不要搞错了。如果是最新的Chrome, 下载最新的chromedriver.exe 就可以了。把chromedriver的路径也加到环境变量里。

    检测:运行这段代码,会自动打开百度

    from selenium import webdriver		# 引入webdriver api
    driver = webdriver.Chrome()		# 使用chrome浏览器声明一个webdriver对象
    driver.get('http://www.baidu.com/')	# 表示使用chrome以get的方式请求百度的url
    driver.find_element_by_id("kw").send_keys("selenium")	# 检索到百度的输入框,输入selenium
    driver.find_element_by_id("su").click()	# 检索到百度的搜索按钮并点击
    

    0x02:元素选取
    在上面的实例中,最重要的就是找到搜索框和搜索按钮对应的元素,然后再进行相应的操作(输入关键字、点击),强大的selenium提供了多种提取元素的方法。

    单个元素提取

    find_element_by_id		# 通过元素id
    find_element_by_name	# 通过name属性
    find_element_by_xpath	# 通过xpath
    find_element_by_link_text	# 通过链接文本
    find_element_by_partial_link_text
    find_element_by_tag_name	# 通过标签名
    find_element_by_class_name		# 通过class名称定位
    find_element_by_css_selector	# 通过css选择器定位
    

    多个元素提取,返回一个列表

    find_elements_by_name
    find_elements_by_xpath
    find_elements_by_link_text
    find_elements_by_partial_link_text
    find_elements_by_tag_name
    find_elements_by_class_name
    find_elements_by_css_selector
    

    0x03:操作元素方法

    • clear 清除元素的内容:clear(self)
    • send_keys 模拟按键输入:send_keys(self, *value)
    • click 点击元素:click(self)
    • submit 提交表单:submit(self)
    • 获取元素属性:get_attribute(self, name)
    • 获取元素文本:text

    0x04:页面操作方法
    from selenium import webdriver

    • 打开浏览器:driver = webdriver.Chrome()
    • 请求一个url:driver.get("www.baidu.com")
    • 返回当前页面的title:title = driver.title
    • 返回当前页面的url:url = driver.current_url
    • 返回当前页面的源码:source = driver.page_source
    • 关闭当前页面:driver.close()
    • 注销并关闭浏览器:driver.quit()
    • 浏览器前进:driver.forward()
    • 浏览器后退:driver.back()
    • 刷新当前页面:driver.refresh()
    • 获取当前session中的全部cookie:get_cookies(self)
    • 获取当前会中中的指定cookie:get_cookie(self, name)
    • 在当前会话中添加cookie:add_cookie(self, cookie_dict)
    • 添加浏览器User-Agent:
      options.add_argument('User-Agent=Mozilla/5.0 (Linux; U; Android 4.0.2; en-us; Galaxy Nexus Build/ICL53F) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30')
    • 添加设置项Chrome Options:
      options = webdriver.ChromeOptions()
      options.add_argument('xxxx')
      driver = webdriver.Chrome(chrome_options=options)

    0x05:页面等待
    既然selenium是使用浏览器发送请求,那么势必会加载一些东西,而且现在的网页越来越多采用了ajax技术。如果代码运行到了提取元素的地方,而这个元素尚未被加载,那么就会报错。为了解决这个问题,selenium提供了两种等待方式,隐式等待显示等待。隐式等待是等待特定的时间,显式等待是指定某一条件直到这个条件成立时继续执行。

    • 隐式等待
      隐式等待比较简单,就是简单地设置一个等待时间,单位为秒。

        from selenium import webdriver
      
        driver = webdriver.Chrome()
        driver.implicitly_wait(10) # seconds
        driver.get("http://somedomain/url_that_delays_loading")
        myDynamicElement = driver.find_element_by_id("myDynamicElement")
      
    • 显式等待
      显式等待指定某个条件,然后设置最长等待时间。如果在这个时间还没有找到元素,那么便会抛出异常了。

        from selenium import webdriver
        from selenium.webdriver.support.ui import WebDriverWait
        driver = webdriver.Chrome()
        driver.get("http://somedomain/url_that_delays_loading")
        try:
            element = WebDriverWait(driver, 10).until(
                EC.presence_of_element_located((By.ID, "myDynamicElement"))
            )
        finally:
            driver.quit()
      

    wait模块的WebDriverWait类是显性等待类,参数如下:

    WebDriverWait(driver, 超时时长, 调用频率, 忽略异常).until(可执行方法, 超时时返回的信息)
    

    这里需要特别注意的是until或until_not中的可执行方法method参数,很多人传入了WebElement对象,如下:

    WebDriverWait(driver, 10).until(driver.find_element_by_id('kw'))  # 错误
    

    这是错误的用法,这里的参数一定要是可以调用的,即这个对象一定有 call() 方法,否则会抛出异常:

    TypeError: 'xxx' object is not callable
    

    在这里,你可以用selenium提供的 expected_conditions 模块中的各种条件,也可以用WebElement的 is_displayed() 、is_enabled()、is_selected() 方法,或者用自己封装的方法都可以。那么接下来我们看一下selenium提供的条件有哪些:

    expected_conditions:

    xpected_conditions是selenium的一个模块,其中包含一系列可用于判断的条件:

    selenium.webdriver.support.expected_conditions(模块)
    
    这两个条件类验证title,验证传入的参数title是否等于或包含于driver.title
    title_is
    title_contains
    
    这两个人条件验证元素是否出现,传入的参数都是元组类型的locator,如(By.ID, 'kw')
    顾名思义,一个只要一个符合条件的元素加载出来就通过;另一个必须所有符合条件的元素都加载出来才行
    presence_of_element_located
    presence_of_all_elements_located
    
    这三个条件验证元素是否可见,前两个传入参数是元组类型的locator,第三个传入WebElement
    第一个和第三个其实质是一样的
    visibility_of_element_located
    invisibility_of_element_located
    visibility_of
    
    这两个人条件判断某段文本是否出现在某元素中,一个判断元素的text,一个判断元素的value
    text_to_be_present_in_element
    text_to_be_present_in_element_value
    
    这个条件判断frame是否可切入,可传入locator元组或者直接传入定位方式:id、name、index或WebElement
    frame_to_be_available_and_switch_to_it
    
    这个条件判断是否有alert出现
    alert_is_present
    
    这个条件判断元素是否可点击,传入locator
    element_to_be_clickable
    
    这四个条件判断元素是否被选中,第一个条件传入WebElement对象,第二个传入locator元组
    第三个传入WebElement对象以及状态,相等返回True,否则返回False
    第四个传入locator以及状态,相等返回True,否则返回False
    element_to_be_selected
    element_located_to_be_selected
    element_selection_state_to_be
    element_located_selection_state_to_be
    
    最后一个条件判断一个元素是否仍在DOM中,传入WebElement对象,可以判断页面是否刷新了
    staleness_of
    

    上面是所有17个condition,与until、until_not组合能够实现很多判断,如果能自己灵活封装,将会大大提高脚本的稳定性。

    0x06:鼠标操作
    在现实的自动化测试中关于鼠标的操作不仅仅是click()单击操作,还有很多包含在ActionChains类中的操作。如下:

    • context_click(elem) 右击鼠标点击元素elem,另存为等行为
    • double_click(elem) 双击鼠标点击元素elem,地图web可实现放大功能
    • drag_and_drop(source,target) 拖动鼠标,源元素按下左键移动至目标元素释放
    • move_to_element(elem) 鼠标移动到一个元素上
    • click_and_hold(elem) 按下鼠标左键在一个元素上
    • perform() 在通过调用该函数执行ActionChains中存储行为

    举例如下图所示,获取通过鼠标右键另存为百度图片logo。代码:

    import time
    from selenium import webdriver
    from selenium.webdriver.common.keys import Keys
    from selenium.webdriver.common.action_chains import ActionChains
     
    driver = webdriver.Firefox()
    driver.get("http://www.baidu.com")
     
    #鼠标移动至图片上 右键保存图片
    elem_pic = driver.find_element_by_xpath("//div[@id='lg']/img")
    print elem_pic.get_attribute("src")
    action = ActionChains(driver).move_to_element(elem_pic)
    action.context_click(elem_pic)
     
    #重点:当右键鼠标点击键盘光标向下则移动至右键菜单第一个选项
    action.send_keys(Keys.ARROW_DOWN)
    time.sleep(3)
    action.send_keys('v') #另存为
    action.perform()
     
    #获取另存为对话框(失败)
    alert.switch_to_alert()
    alert.accept()
    

    0x07:键盘操作
    在webdriver的Keys类中提供了键盘所有的按键操作,当然也包括一些常见的组合键操作如Ctrl+A(全选)、Ctrl+C(复制)、Ctrl+V(粘贴)。

    • send_keys(Keys.ENTER) 按下回车键
    • send_keys(Keys.TAB) 按下Tab制表键
    • send_keys(Keys.SPACE) 按下空格键space
    • send_keys(Kyes.ESCAPE) 按下回退键Esc
    • send_keys(Keys.BACK_SPACE) 按下删除键BackSpace
    • send_keys(Keys.SHIFT) 按下shift键
    • send_keys(Keys.CONTROL) 按下Ctrl键
    • send_keys(Keys.ARROW_DOWN) 按下鼠标光标向下按键
    • send_keys(Keys.CONTROL,'a') 组合键全选Ctrl+A
    • send_keys(Keys.CONTROL,'c') 组合键复制Ctrl+C
    • send_keys(Keys.CONTROL,'x') 组合键剪切Ctrl+X
    • send_keys(Keys.CONTROL,'v') 组合键粘贴Ctrl+V

    这里使用的例子参考虫师的书籍《selenium2 python自动化测试》

    import time
    from selenium import webdriver
    from selenium.webdriver.common.keys import Keys
     
    driver = webdriver.Firefox()
    driver.get("http://www.baidu.com")
     
    #输入框输入内容
    elem = driver.find_element_by_id("kw")
    elem.send_keys("Eastmount CSDN")
    time.sleep(3)
     
    #删除一个字符CSDN 回退键
    elem.send_keys(Keys.BACK_SPACE)
    elem.send_keys(Keys.BACK_SPACE)
    elem.send_keys(Keys.BACK_SPACE)
    elem.send_keys(Keys.BACK_SPACE)
    time.sleep(3)
     
    #输入空格+"博客"
    elem.send_keys(Keys.SPACE)
    elem.send_keys(u"博客")
    time.sleep(3)
     
    #ctrl+a 全选输入框内容
    elem.send_keys(Keys.CONTROL,'a')
    time.sleep(3)
     
    #ctrl+x 剪切输入框内容
    elem.send_keys(Keys.CONTROL,'x')
    time.sleep(3)
     
    #输入框重新输入搜索
    elem.send_keys(Keys.CONTROL,'v')
    time.sleep(3)
     
    #通过回车键替代点击操作
    driver.find_element_by_id("su").send_keys(Keys.ENTER)
    time.sleep(3)
     
    driver.quit()
    
  • 相关阅读:
    LightOJ 1132 Summing up Powers(矩阵快速幂)
    hdu 3804 Query on a tree (树链剖分+线段树)
    LightOJ 1052 String Growth && uva 12045 Fun with Strings (矩阵快速幂)
    uva 12304 2D Geometry 110 in 1! (Geometry)
    LA 3263 That Nice Euler Circuit (2D Geometry)
    2013 SCAUCPC Summary
    poj 3321 Apple Tree (Binary Index Tree)
    uva 11796 Dog Distance (几何+模拟)
    uva 11178 Morley's Theorem (2D Geometry)
    动手动脑
  • 原文地址:https://www.cnblogs.com/liangshian/p/11587233.html
Copyright © 2011-2022 走看看