• 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()
    
  • 相关阅读:
    在windows系统和linux系统中查询IP地址命令的不同
    Linux --忘记root密码/su: Authentication failure
    Spring+quartz集群解决多服务器部署定时器重复执行的问题
    spring定时任务scheduler集群环境下指定运行服务器防止多服务器多次执行
    跨库数据表的运算
    AspectJ 切面注解中五种通知注解:@Before、@After、@AfterRunning、@AfterThrowing、@Around
    JUnit4 中@AfterClass @BeforeClass @after @before的区别对比
    Java后端的学习之Spring基础
    MySQL 5.7默认ONLY_FULL_GROUP_BY语义介绍
    【可靠性】Mysql 5.7 降低了半同步复制-数据丢失的风险
  • 原文地址:https://www.cnblogs.com/liangshian/p/11587233.html
Copyright © 2020-2023  润新知