🔥《手把手教你》系列基礎篇之 3-python+ selenium 自動化測試 - 驅動瀏覽器和元素定位大法(詳細)

北京-宏哥發表於2024-11-19

1. 簡介

上一篇中,只是簡單地一帶而過的說了一些驅動瀏覽器,這一篇繼續說說驅動瀏覽器,然後再說一說元素定位的方法。

完成環境的安裝並測試之後,我們對 Selenium 有了一定的瞭解了,接下來我們繼續驅動瀏覽器做一些基本操作:

視窗尺寸設定、網頁截圖、重新整理、前進和後退

2. 視窗尺寸設定

在測試過程中,我們可能會要求開啟瀏覽器的視窗處於最大化或者設定為某一特定尺寸的大小,所以我們使用 selenium 驅動瀏覽器時設定視窗大小

# coding=utf-8🔥

# 1.先設定編碼,utf-8可支援中英文,如上,一般放在第一行

# 2.註釋:包括記錄建立時間,建立人,專案名稱。
'''
Created on 2019-11-26
@author: 北京-宏哥   QQ交流群:705269076
Project: python+ selenium-驅動瀏覽器和元素定位大法
'''

# 3.匯入模組

import time

from selenium import webdriver

driver = webdriver.Chrome() # 啟動chrome

def get_size(driver):
    """
    獲取視窗尺寸並列印

    """
    size = driver.get_window_size() # 獲取視窗尺寸
    print(size) # 列印視窗尺寸
    time.sleep(3) # 暫停3秒

driver.get("https://image.baidu.com/search/down?url=https://www.google.com") # 開啟網頁
get_size(driver)
driver.set_window_size(800,600) # 設定視窗尺寸為800*600
get_size(driver)
driver.minimize_window() # 視窗最小化,視窗尺寸未發生變化
get_size(driver)
driver.maximize_window() # 視窗最大化
get_size(driver)

driver.quit() # 停止程序

3. 網頁截圖

在完成開啟網頁時,我們對網頁內容進行儲存的方式的一種就是進行網頁截圖,webdriver 中就提供了截圖的選擇

# coding=utf-8🔥

# 1.先設定編碼,utf-8可支援中英文,如上,一般放在第一行

# 2.註釋:包括記錄建立時間,建立人,專案名稱。
'''
Created on 2019-11-26
@author: 北京-宏哥   QQ交流群:705269076
Project: python+ selenium-驅動瀏覽器和元素定位大法
'''

# 3.匯入模組

from selenium import webdriver

driver = webdriver.Chrome() # 建立driver物件,啟動chrome

driver.get("https://image.baidu.com/search/down?url=https://www.google.com") # 開啟網頁
driver.get_screenshot_as_file("D:\\screenshot.png") # 截圖

driver.quit() # 停止程序

4. 重新整理、前進和後退

如同在瀏覽器中進行常規按鈕操作,依次開啟多個網頁後,需要對網頁重新整理,返回、前進

# coding=utf-8🔥

# 1.先設定編碼,utf-8可支援中英文,如上,一般放在第一行

# 2.註釋:包括記錄建立時間,建立人,專案名稱。
'''
Created on 2019-11-26
@author: 北京-宏哥   QQ交流群:705269076
Project: python+ selenium-驅動瀏覽器和元素定位大法
'''

# 3.匯入模組

import time
from selenium import webdriver

driver = webdriver.Chrome()

# 開啟兩個網頁
driver.get("https://image.baidu.com/search/down?url=https://www.baidu.com") 
time.sleep(3)
driver.get("https://image.baidu.com/search/down?url=https://www.google.com")
time.sleep(3)

# 進行後退、前進操作
driver.back() # 後退
time.sleep(3)
driver.forward() # 前進
time.sleep(3)

# 對網頁進行重新整理
driver.refresh()

driver.quit()

一些基本操作就完成了,接下來我們就可以做更多~

5.定位大法

webdriver 提供了八種元素定位方法:

id
name
class name
tag name
link text
partial link text
xpath
css selector

在 Python 語言中對應的定位方法如下:

find_element_by_id()
find_element_by_name()
find_element_by_class_name()
find_element_by_tag_name()
find_element_by_link_text()
find_element_by_partial_link_text()
find_element_by_xpath()
find_element_by_css_selector()

下面我們就逐一的來看這些定位方法的使用。在此之前,我們拷取百度首頁的前端程式碼,以定位頁面上的元素為例進行講解。

<html>
<head>
<body>
<script>
<div id="wrapper" style="display: block;">
<div id="debug" style="display:block;position:..">
<script>
<div id="head" class="s_down">
<div class="head_wrapper">
<div class="s_form">
<div class="s_form_wrapper">
<div id="lg">
<a id="result_logo" onmousedown="return .." href="/">
<form id="form" class="fm" action="/s" name="f">
<input type="hidden" value="utf-8" name="ie">
<input type="hidden" value="8" name="f">
<input type="hidden" value="1" name="rsv_bp">
<input type="hidden" value="1" name="rsv_idx">
<input type="hidden" value="" name="ch">
<input type="hidden" value="02.." name="tn">
<input type="hidden" value="" name="bar">
<span class="bg s_ipt_wr">
<input id="kw" class="s_ipt" autocomplete="off"
maxlength="100" value="" name="wd">
</span>
<span class="bg s_btn_wr">
<input id="su" class="bg s_btn" type="submit"
value="百度一下">
</span>
....
</body>
</html>hello

注意這段程式碼並非百度首頁的頁面原始碼,而是透過前端工具檢視所得到頁面程式碼與結構。那麼這樣的 HTML 結構有如下特徵。

(1)它們由標籤對組成:

<html></html>
<body></body>
<div></div>
<form></form>

那麼 html、div 就是標籤的標籤名。

(2)標籤各種屬性屬性:

<div id="head" class="s_down">
<from class="well">
<input id="kw" name="wd" class="s_ipt">

就像人一樣也會有各種屬性,身份證號(id)、姓名(name)、職業(class)等。

(3)標籤對之間可以有文字資料。

<a>新聞</a>
<a>hao123</a>
<a>地圖</a>

(4)標籤有由層級關係

<html>
    <body>
    </body>
</html>
<div>
    <from>
        <input />
    </from>
<div>

對於上面結構,如果把 input 看作是子標籤,那麼 form 就是它的父標籤。

理解了上面這些特性是學習定位方法的基礎。我們以百度輸入框和百度搜尋按鈕為例來學習不同的定位方法,兩個元素的程式碼如下。

……
<input id="kw" class="s_ipt" autocomplete="off" maxlength="100" value=""name="wd">
……
<input id="su" class="bg s_btn" type="submit" value="百度一下">

5.1 id 定位

name 如果把頁面上看元素看作一個人的話,如果我們想找一個人如何去找,那麼這個人一定有其別於其它人的 “屬性”,比如他的身份證號一定和別人不一樣,他的名字和別人不一樣。那麼我們就可以透過身證號和名字來找到一個人。那麼 id 就可以看做是一個人的身

份號,當然這個 id 並不像我們現實中的身份證號有那麼強的唯一性,如果在一個頁面上發現有兩個元素的 id="kw"也是不足為奇的,這個取決前端程式碼的規範程度。

對百度首頁上的輸入框與百度搜尋按鈕來說,定位方法如下:

find_element_by_id("kw")
find_element_by_id("su")
find_element_by_id()方法用於元素中 id 屬性的定位。

5.2 name 定位

name 的定位與 id 類似,每一個人都會有名字,那麼 name 就可作是一個元素的名字。透過 name 定位輸入框:

find_element_by_name("wd")

find_element_by_name() 方法用於元素中 name 屬性的定位,百度搜尋按鈕並沒有提供 name 屬性,那麼我們就不能透過 name 去定位百度搜尋按鈕。

5.3 class 定位

class 也是不少元素會有的一個屬性,它的定位和 name 以及 id 類似,下面透過 class 去定位百度輸入框和百度搜尋按鈕:

find_element_by_class_name("s_ipt")
find_element_by_class_name("bg s_btn")
find_element_by_class_name()方法用於元素中 class 屬性的定位。

5.4 tag 定位

tag 定位取的是一個元素的標籤名,透過標籤名去定位單個元素的唯一性最底,因為在一個頁面中有太多的元素標籤為

和了,所以很難透過標籤名去區分不同的元素。

透過標籤名定位百度首頁上的輸入框與百度搜尋按鈕:

find_element_by_tag_name("input")
find_element_by_tag_name("input")

find_element_by_tag_name() 方法透過元素的 tag name 來定位元素。透過上面的例子,我們並不能區別不同的元素,因為在一個頁面上標籤名相同很難以避免。

link 定位與前面介紹的幾種定位方法有所不同,它專門用來定位本連結。百度輸入框上面的幾個文字連結的程式碼如下:

<a class="mnav" name="tj_trnews" href="http://news.baidu.com">新聞</a>
<a class="mnav" name="tj_trhao123" href="http://www.hao123.com">hao123</a>
<a class="mnav" name="tj_trmap" href="http://map.baidu.com">地圖</a>
<a class="mnav" name="tj_trvideo" href="http://v.baidu.com">影片</a>
<a class="mnav" name="tj_trtieba" href="http://tieba.baidu.com">貼吧>

透過檢視上面的程式碼,我們發現透過 name 屬性定位是個不錯的選擇。不過我們這裡為了要學習 link 定位,透過 link 定位實現如下:

find_element_by_link_text("新聞")
find_element_by_link_text("hao123")
find_element_by_link_text("地圖")
find_element_by_link_text("影片")
find_element_by_link_text("貼吧")

find_element_by_link_text() 方法透過元素標籤對之間的文字資訊來定位元素。不過,需要強調的是 Python 對於中文的支援並不好,如查 Python 在執行中文的地方出現在亂碼,可以在中檔案字串的前面加個小 “u” 可以有效的避免亂碼的問題,加 u 的作用是把中文字

符串轉換中 unicode 編碼,如:

find_element_by_link_text(u"新聞")

parial link 定位是對 link 定們的一個種補充,有些文字連線會比較長,這個時候我們可以取文字連結的有一部分定位,只要這一部分資訊可以唯一的標識這個連結。

<a class="mnav" name="tj_lang" href="#">一個很長很長的文字連結</a>

透過 partial link 定位如下:

find_element_by_partial_link_text("一個很長的")
find_element_by_partial_link_text("文字連線")

find_element_by_link_text() 方法透過元素標籤對之間的部分文字資訊來定位元素。

6. 定位元素

selenium 提供了多種方式進行定位元素: *find_element_by_ **

1 find_element_by_id
2 find_element_by_name
3 find_element_by_xpath
4 find_element_by_link_text
5 find_element_by_partial_link_text
6 find_element_by_tag_name
7 find_element_by_class_name
8 find_element_by_css_selector

當然也可以一次定位多個元素: *find_elements_by_ **

1 find_elements_by_name
2 find_elements_by_xpath
3 find_elements_by_link_text
4 find_elements_by_partial_link_text
5 find_elements_by_tag_name
6 find_elements_by_class_name
7 find_elements_by_css_selector

因為 id 是唯一的,所以一次定位多個元素是沒有辦法透過 id 進行定位的。

同樣,可以透過 find_element 和 **find_elements ,不過使用之前需要匯入 by 類, **from selenium.webdriver.common.by import By 。

# coding=utf-8🔥

# 1.先設定編碼,utf-8可支援中英文,如上,一般放在第一行

# 2.註釋:包括記錄建立時間,建立人,專案名稱。
'''
Created on 2019-11-26
@author: 北京-宏哥   QQ交流群:705269076
Project: python+ selenium-驅動瀏覽器和元素定位大法
'''

# 3.匯入模組

import time
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
# 開啟一個網頁
driver.get("https://image.baidu.com/search/down?url=https://www.zhihu.com/")

# 查詢一個元素的方法
ele = driver.find_element_by_xpath(
    '//*[@id="root"]/div/div[2]/header/div/nav/a[2]')

ele.click() # 點選已定位的元素
driver.back() # 退回

time.sleep(5)
ele = driver.find_element(
    By.XPATH, '//*[@id="root"]/div/div[2]/header/div/nav/a[2]')
# ID = "id"
# XPATH = "xpath"
# LINK_TEXT = "link text"
# PARTIAL_LINK_TEXT = "partial link text"
# NAME = "name"
# TAG_NAME = "tag name"
# CLASS_NAME = "class name"
# CSS_SELECTOR = "css selector"

ele.click()
driver.back()

# 查詢多個元素的方法
eles = driver.find_elements_by_class_name("Feed")

print(eles)
print(len(eles))

time.sleep(5)
eles = driver.find_elements(By.CLASS_NAME, 'Feed')
# XPATH = "xpath"
# LINK_TEXT = "link text"
# PARTIAL_LINK_TEXT = "partial link text"
# NAME = "name"
# TAG_NAME = "tag name"
# CLASS_NAME = "class name"
# CSS_SELECTOR = "css selector"

print(eles)
print(len(eles))

driver.quit()

以上就是定位元素的一些方法。說明下 xpath 是比較好用的方式,之後可以多多練習使用 xpath 進行定位元素。

前面所介紹的幾種定位方法相對來說比較簡單,我們理想狀態下在一個頁面當中每一個元素都會有一個唯一 id 和 name 屬性值,我們透過它的屬性值來找到他們,但在實際的專案中並非想象的這般美好。有時候一個元素並沒有 id 或 name 屬性,或者會有多個元素的

id 和 name 屬性值是一樣的,又或者每一次重新整理頁面,id 的值都會隨機變化。那麼在這種情況下我們如何來定位元素呢?

下面一篇介紹 xpath 與 CSS 定位相比上面介紹的方式來說比較難理解,但他們的靈活的定位能力遠比上面的幾種方式要強大得多。

那麼下面宏哥接下來就分享一下 xpath 的相關知識。

7. 小結

  好了,今天 python+ selenium-驅動瀏覽器和元素定位大法就分享到這裡。

相關文章