一.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。