【Python】Selenium之webdriver

一.Webdriver原理

方法直接调用就可以理解,这里我们需要查看源码数据

举个例子

Webdriver中最小化window语句

driver.minimize_window()

查看源码

    def minimize_window(self):
        """
        Invokes the window manager-specific 'minimize' operation
        """
        self.execute(Command.MINIMIZE_WINDOW)

excute()方法就是执行一个命令返回json响应

    def execute(self, driver_command, params=None):
        """
        Sends a command to be executed by a command.CommandExecutor.

        :Args:
         - driver_command: The name of the command to execute as a string.
         - params: A dictionary of named parameters to send with the command.

        :Returns:
          The command's JSON response loaded into a dictionary object.
        """
        if self.session_id is not None:
            if not params:
                params = {'sessionId': self.session_id}
            elif 'sessionId' not in params:
                params['sessionId'] = self.session_id

        params = self._wrap_value(params)
        response = self.command_executor.execute(driver_command, params)
        if response:
            self.error_handler.check_response(response)
            response['value'] = self._unwrap_value(
                response.get('value', None))
            return response
        # If the server doesn't send a response, assume the command was
        # a success
        return {'success': 0, 'value': None, 'sessionId': self.session_id}

Command类是一个命令的集合类

MINIMIZE_WINDOW = "minimizeWindow"

在查找源码之后,发现最终还是使用urllib3以及request接口获取数据

二.Webdriver简单命令

import time
from selenium.webdriver import Chrome


driver = Chrome()
driver.get('http://www.baidu.com')
time.sleep(3)

# 最小化
driver.minimize_window()

# 最大化
driver.maximize_window()

# 访问豆瓣(获取新的url)
driver.get('http://www.douban.com')

# 后退
driver.back()

# 前进
driver.forward()

# 刷新
driver.refresh()

# 关闭标签页,当只有一个标签打开的时候, 执行close就相当于额关闭了浏览器。
driver.close()

# 关闭浏览器(全部标签)
driver.quit()

操作介绍

# 获取网页标题
print(driver.title)

# 获取 URL
print(driver.current_url)

# 保存截屏
driver.save_screenshot('test.png')

# 获取窗口句柄——窗口id,名字等。
print(driver.current_window_handle)

进阶操作

获取查找的元素的name属性

from selenium import webdriver
driver = webdriver.Chrome()
url = "http://www.baidu.com"
driver.get(url)

ele = driver.find_element_by_xpath("//*[@id='u1']/a[1]")
ele_name = ele.get_attribute("name")
print(ele_name)

找到输入框元素——输入文本

ele.send_keys("HELLO WORLD")

找到提交按钮——提交输入的文本

submit_ele = driver.find_element_by_id('su')
submit_ele.click()

三.等待

在页面正在加载中执行find_element(),出现报错No Such Element, Element can not located.

原因:

  • 元素表达式有问题
  • 没有等待
  • 元素不可用,(隐藏,不能用)

1.使用time.sleep

sleep函数使用的是固定的时间等待,这种等待最死板,会因为网络波动影响效果

2.显示等待-WebDriverWait()

显示等待定义的等待条件,只有特定的条件触发之后,Webdriver才会执行后续操作。
相比与sleep(10)需要等待10秒。如果3秒就达到等待条件的话,就不需要多出来的7秒;如果没有等到需要的元素超时就上报异常。

特点:在设置时间内,默认每隔一段时间检测一次当前页面元素是否存在,如果超过设置时间检测不到则抛出异常。默认检测频率为0.5s。

示例展示:

try:
    element = WebDriverWait(driver,10).until(
        expected_conditions.text_to_be_present_in_element((By.XPATH,"//*[@id='u1']/a[1]"))
    )
    ele_name = element.get_attribute("name")
    print(ele_name)
finally:
    driver.quit()

解析:

1)Webdriver
class WebDriverWait(object):
    def __init__(self, driver, timeout, poll_frequency=POLL_FREQUENCY, ignored_exceptions=None):
  • driver:浏览器驱动
  • timeout:最长超时等待时间
  • poll_frequency:检测的时间间隔,默认为500ms
  • ignore_exception:超时后抛出的异常信息,默认情况下抛 NoSuchElementException 异常
2)在使用Wevdriver的时候配合until方法使用
until(method, message='')
#调用该方法体提供的回调函数作为一个参数,直到返回值为True

until_not(method, message='')
#调用该方法体提供的回调函数作为一个参数,直到返回值为False
3)结合Expected Conditions类条件判断
  • title_is:判断当前页面的title是否等于预期
  • title_contains:判断当前页面的title是否包含预期字符串
  • presence_of_element_located:判断某个元素是否被加到了dom树里,并不代表该元素一定可见
  • visibility_of_element_located:判断某个元素是否可见. 可见代表元素非隐藏,并且元素的宽和高都不等于0
    -等等

3.隐式等待-implicitly_wait()

隐式等待则是Webdriver等待一定时间,该时间内如果网页加载完毕,就执行下一步,否则要等待时间截止,再执行下一步

优点:程序不会因为找不到元素卡死(显示等待)

注意:隐式等待是针对整个driver周期都起作用,所以只用设置一次即可

from selenium import webdriver

driver = webdriver.Chrome()
driver.get( "http://www.baidu.com")
driver.minimize_window()
driver.implicitly_wait(10) # seconds

try:
    element = driver.find_element_by_xpath("//*[@id='u1']/a[1]")
    ele_name = element.get_attribute("name")
    print(ele_name)
finally:
    driver.quit()

四.Webdriver二次封装

二次封装查找方法,便于使用

from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait

class WebDriver(object):
    def __init__(self,driver):
        self.driver = driver

    def find_element(self,locator):
        element = WebDriverWait(self.driver,10).until(lambda x:x.find_element(*locator))
        return element

    def send_keys(self, locator, text):
        self.find_element(locator).send_keys(text)

    def click(self, locator):
        self.find_element(locator).click()

if __name__ == '__main__':
    driver = webdriver.Chrome()
    url = "http://www.baidu.com"
    driver.get(url)
    mydriver = WebDriver(driver)
    # loc =  ("id", "kw")
    # res = mydriver.find_element(loc)
    # print(res)

lambda表达式

lambda表达式通常在需要使用一个函数的时候,但是由不想去命名一个函数的场合下使用,也就是匿名函数,通常都用来表示简单的函数。

add = lambda x, y : x+y
add(1,2)  
# 结果为3

函数注解

def happy(x:int,y:int) -> int:
    '''print happy '''
    res = x+y
    return res
1.函数参数注解

因为Python和C或者java不同,在设定函数的时候没有限制数据类型,这里可以从函数注解的角度标记下,但是实际上这个是没有任何限制的。

#参数返回值注解,以字典形式存在
print(happy.__annotations__)
2.函数文档注解

函数文档注解,在函数定义的下面一行使用字符串注释可以用于做文档

print(happy.__doc__)
3.变量注解

在设定变量的时候注解,同样实际上是没有限制的

a:int = 1000

五.问题

1.为什么python不可以通过webdriver修改元素属性?

显而易见的啊,python只是通过js获取网页的元素,元素都是已经给定的,当然不可以修改。
如果需要的话通过js。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章