【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。

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