Selenium自動化入坑指南

語言: CN / TW / HK

前言

在日常工作中,一些在web頁面上操作起來比較繁瑣而又持續的工作,是不是很枯燥,隨之就誕生了實現自動化的想法,一鍵finish該多好。接下來就為大家介紹這款工具,實現起來綽綽有餘。它就是Selenium。

而通俗易懂的話就是可以通過它,寫出自動化程式,跟人一樣在瀏覽器操作web介面,比如點選、拖拽介面按鈕,文字框輸入文字,從web介面獲取資訊等,然後用程式進行分析處理。

接下來就帶大家入坑Selenium,因為內容太多,本文章將分一、二兩節進行講解。

一. 環境準備

1、安裝selenium庫

需要安裝python(推薦3.7+)環境,然後直接用pip install selenium安裝依賴包即可。

pip install selenium

2、安裝瀏覽器驅動

驅動下載完成後,可對其進行環境變數配置,也就是將對應的ChromeDriver的可執行檔案chromedriver.exe檔案拖到Python的Scripts目錄下,或也可以在指令碼呼叫的時候指定下驅動的路徑即可。當然我的習慣是後者。 各瀏覽器的下載驅動及表達方式
  • Safari瀏覽器驅動 : safaridriver

  • Firefox瀏覽器驅動 :geckodriver

  • IE瀏覽器驅動 :IEDriverServer

  • Edge瀏覽器驅動 :MicrosoftWebDriver

  • Opera瀏覽器驅動 :operadriver

  • Chrome瀏覽器驅動 :chromedriver

二、基本用法

1、建立瀏覽器物件

下面的程式碼,實現自動化的開啟Chrome瀏覽器,訪問潮啟移動端安全管控平臺網站

# coding = utf-8
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from time import sleep

# 建立 WebDriver 物件,指明使用chrome瀏覽器驅動
wd = webdriver.Chrome(service=Service(r'/Users/Desktop/chromedriver'))

#設定等待時間5秒
sleep(5)

# 呼叫WebDriver 物件的get方法 可以讓瀏覽器開啟指定網址
wd.get('http://app.sdsecurity.org.cn:8181’)

#退出瀏覽器
 wd.quit()

wd = webdriver.Chrome(service=Service(r'/Users/Desktop/chromedriver'))

等號左邊是給等號右邊的操作進行命名, 等號右邊返回的是 WebDriver 型別的物件,我們可以通過這個物件來操控瀏覽器,比如 開啟網址、選擇介面元素等。若想更換瀏覽器,像火狐、IE都可以,只需要安裝好對應的瀏覽器,將啟動物件改為相應瀏覽器就可以了,像這樣:

啟動Firefox瀏覽器:
from selenium import webdriverbrowser = webdriver.Firefox()browser.get('URL')
啟動IE瀏覽器:
from selenium import webdriverbrowser = webdriver.Ie()browser.get('URL')

使用 WebDriver 的 get 方法 開啟該目標網址。執行這行程式碼時,自動化程式就發起了 開啟該目標網址的請求訊息,通過瀏覽器驅動,給 Chrome瀏覽器。

wd.get('http://app.sdsecurity.org.cn:8181')

.quit()
.close()

當然以上程式碼呈現的是有介面的瀏覽器,我們還可以初始化瀏覽器為 無介面的瀏覽器 ,相當於隱式操作

from selenium import webdriver
from selenium.webdriver.chrome.service import Service

# 無介面的瀏覽器
option = webdriver.ChromeOptions()
option.add_argument("headless")
wd = webdriver.Chrome(options=option,service=Service(r'/Users/Desktop/chromedriver 2'))

# 訪問潮啟移動端管控安全管控平臺
wd.get(r'http://app.tidesec.com')
# 截圖預覽
wd.get_screenshot_as_file('截圖.png')

完成瀏覽器物件的初始化後,將其賦值給了wd物件,接下來我們可以呼叫wd來執行各種方法模擬瀏覽器的操作

2、頁面訪問

進行頁面訪問使用的是get方法,傳入引數為待訪問頁面的URL地址即可。

from selenium import webdriver
from selenium.webdriver.chrome.service import Service

# 初始化瀏覽器為chrome瀏覽器
wd = webdriver.Chrome(service=Service(r'/Users/Desktop/chromedriver 2'))

# 訪問潮啟移動端管控安全管控平臺
wd.get(r'http://app.tidesec.com')
 
# 關閉瀏覽器
wd.quit()

3、控制瀏覽器大小

set_window_size()方法可以用來設定瀏覽器大小(就是解析度),而 maximize_window 則是設定瀏覽器為全屏

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
import time
wd = webdriver.Chrome(service=Service(r'/Users/Desktop/chromedriver 2'))

# 設定瀏覽器大小:全屏
wd.maximize_window()

wd.get(r'http://app.tidesec.com')
time.sleep(2)

# 設定解析度 1000*800
wd.set_window_size(1000, 800)
time.sleep(2)

# 關閉瀏覽器
wd.quit()

4、前後切換

實現切換上一頁或下一頁操作,也是我們比較常見的操作,這裡可以用forward()方法來實現切換下一頁,back()方法切換下一頁

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
import time

wd = webdriver.Chrome(service=Service(r'/Users/Desktop/chromedriver 2'))

#訪問潮聲漏洞檢測平臺
wd.get(r'http://poc.tidesec.com')
time.sleep(2)

#訪問潮星線上CTF平臺
wd.get('http://ctf.tidesec.com/')
time.sleep(2)

# 切換到上一頁面:潮啟移動端安全管控平臺
wd.back()
time.sleep(2)

# 切換下一頁面:潮星線上CTF平臺
wd.forward()
time.sleep(2)
# 關閉瀏覽器
wd.quit()

5、頁面重新整理

refresh()方法可以用來進行瀏覽器頁面重新整理

 try:
    # 重新整理頁面
    wd.refresh()  
    print('重新整理頁面')
except Exception as e:
    print('重新整理失敗')

三、獲取元素資訊

獲取元素的文字內容

element = wd.find_element(By.ID, 'animal')
print(element.text)

獲取元素屬性

element = wd.find_element(By.ID, 'input_name')
print(element.get_attribute('class'))

獲取整個元素對應的HTML

print(element.get_attribute('innerHTML'))

獲取輸入框裡面的文字

element = wd.find_element(By.ID, "input1")
print(element.get_attribute('value')) # 獲取輸入框中的文字

獲取元素文字內容2

可以嘗試使用

 element.get_attribute('innerText') ,或者 element.get_attribute('textContent’)

獲取其他屬性,除了屬性和文字值外,還有id、位置、標籤名和大小等屬性。

element = wd.find_element(By.ID, "input1")
print(element.id)
print(element.location)
print(element.tag_name)
print(element.size)

使用 innerText 和 textContent 的區別是,前者只顯示元素可見文字內容,後者顯示所有內容(包括display屬性為none的部分)

四、定位元素

1、根據ID定位、Name定位

潮星線上CTF平臺

element = wd.findElement(By.id ,'q') #id定位元素
或
element = wd.findElement(By.NAME ,'q') #id定位元素

鎖定搜尋框處,可以選擇性對其搜尋框內容進行清空

element.clear() #清空物件內容

接下來就是輸入字串,進行查詢操作,查詢操作可以有兩種方式,回車或點選查詢

element.send_keys(‘XXX\n’)  #\n是回車wd.find_element(By.CLASS_NAME,'btn’).click() #定位搜尋按鈕並進行點選

當然往往會因為網路延遲等原因會導致指令碼執行報錯的現象,可以在每項操作結束增加等待時間,以保證指令碼正常執行

from time import sleep #載入sleep模組
sleep(2) #等待2秒

以下就是實現自動化查詢操作程式碼

wd = webdriver.Chrome(service=Service(r'/Users/Desktop/chromedriver 2'))# 呼叫WebDriver 物件的get方法 可以讓瀏覽器開啟指定網址

wd.get('http://ctf.tidesec.com/users')

element = wd.find_element(By.ID, 'q')# 根據id選擇元素,返回的就是該元素對應的WebElement物件

element = wd.find_element(By.NAME, 'q')# 根據Name選擇元素,返回的就是該元素對應的WebElement物件

element.clear() # 清除輸入框已有的字串

sleep(2)element.send_keys('dream\n') # 通過該 WebElement物件,就可以對頁面元素進行操作了;比如輸入dream到這個輸入框裡進行回車

2、根據class屬性、tag標籤名定位

潮啟移動端安全管控平臺

wd = webdriver.Chrome(service=Service(r'/Users/Desktop/chromedriver 2'))# 呼叫WebDriver 物件的get方法 可以讓瀏覽器開啟指定網址

wd.get('http://app.tidesec.com')

element = wd.find_element(By.CLASS_NAME, 'search-input')  #根據class屬性鎖定元素

element.clear() # 清除輸入框已有的字串

sleep(2)

element.send_keys('1\n')
#通過該 WebElement物件,就可以對頁面元素進行操作了,比如輸入字串到這個輸入框裡

我們還可利用 tag標籤名
names = wd.find_elements(By.TAG_NAME,'td’)
#根據 tag name 選擇元素,返回的是 一個列表
# 裡面 都是 tag 名為 div 的元素對應的 WebElement物件

for name in names:
  print(name.text)
#取出列表中的每個 WebElement物件,打印出其text屬性的值
# text屬性就是該 WebElement物件對應的元素在網頁中的文字內容

find_element 和 find_elements 的區別

經過上述瞭解,我們也知道了find_element方法是用來定位元素的,但+s和不加還是又區別的。像 find_element()選擇的是符合條件的第一個元素 ,所以這適用於我們只查詢一個元素的時候;而 find_elements選擇的是符合條件的所有元素 ,所以像我們查詢多個元素的時候或一類元素的時候,就用+s的,想上述例子,我們想要獲取查詢後所有<td>標籤文字內容

3、使用link、partial_link 定位

link

Tide安全文庫

ok,開始編寫指令碼,實現自動化訪問文庫,並進入技術文章,並輸出所有文章標題

wd = webdriver.Chrome(service=Service(r'/Users/guozilong/Desktop/chromedriver 2'))

wd.get(r'http://wiki.tidesec.com/') ##訪問Tide安全文庫

element = wd.find_element(By.LINK_TEXT,('技術文章'))#使用link定位文字連結

element.click() #點選element

titles=wd.find_elements(By.TAG_NAME,'a')

for title in titles:
     print(title.text)


wd.quit() # 關閉瀏覽器

partial_link

翻譯過來呢,就是採用部分連結,由於有些連結的文字內容比較 長,這時候可以使用partial_link()選用部分文字進行定位,還是上述例子。編寫指令碼實現自動化訪問文庫,進入人工智慧專欄,輸出所有文章標題

wd = webdriver.Chrome(service=Service(r'/Users/guozilong/Desktop/chromedriver 2'))

wd.get(r'http://wiki.tidesec.com/') ##訪問Tide安全文庫

element = wd.find_element(By.PARTIAL_LINK_TEXT,('人工'))#使用link定位文字連結

element.click() #點選element

titles=wd.find_elements(By.TAG_NAME,'a')

for title in titles:
     print(title.text)

4、xpath、CSS定位

前面介紹的幾種定位方法都是在理想狀態下,有一定使用範圍的,那就是:在當前頁面中,每個元素都有一個唯一的id或name或class或超連結文字的屬性,那麼我們就可以通過這個唯一的屬性值來定位他們。

但是在實際工作中並非有這麼美好,有時候我們要定位的元素並沒有id,name,class屬性,或者多個元素的這些屬性值都相同,又或者重新整理頁面,這些屬性值都會變化。那麼這個時候我們就只能通過xpath或者CSS來定位了。

4.1 先說xpath

以百度網站進行說明,編寫指令碼,通過xpath定位其搜尋框,並輸入xpath進行查詢

wd = webdriver.Chrome(service=Service(r'/Users/guozilong/Desktop/chromedriver 2'))
wd.get(r'http://www.baidu.com') ##訪問Tide安全文庫
element = wd.find_element(By.XPATH,("//*[@id='kw']"))#通過id查詢元素
element.send_keys('xpath\n') #物件內輸入xpath並回車

4.1.2 xpath相對路徑定位

以//開頭,//標籤名[@屬性名="屬性值"] 如://form//input[@name="phone"]

find_element(By.XPATH,("//*[@id='kw']")) #通過元素id查詢元素

find_element(By.XPATH,("//*[@name='wd']")) #通過元素name查詢元素

find_element(By.XPATH,("//*[@class='s_ipt']")) #通過元素class查詢元素

find_element(By.XPATH,("//*[@maxlength='255']")) #通過元素其他查詢元素

前面的*表示查詢所有的標籤元素,可以替換為標籤名稱,更準確的定位元素

4.1.3 xpath絕對路徑定位

以/開頭,但是要從根目錄開始,比較繁瑣,可以通過瀏覽器檢視元素屬性,右擊複製xpath快速生成。一般不建議使用。如:/html/body/div/a

4.1.4 xpath層級關係定位

find_element(By.XPATH,("//input[@id='form']//span[1]//input")) 

4.2 再說CSS

css(Cascading Style Sheets)是一種語言,它用來描述HTML和XML的元素顯示樣式。而css的定位方式比xpath效率快,語法也很強大,所以非常推薦這種方式定位。下面介紹下css定位的幾種方式:

4.2.1 id選擇器

說明:根據元素id屬性來選擇 格式:#id屬性值

element = wd.find_element(By.CSS_SELECTOR,('#kw'))  #通過css id屬性定位

4.2.2 class選擇器

說明:根據元素class屬性來選擇 格式:.class屬性值

element = wd.find_element(By.CSS_SELECTOR,('.s_ipt'))  #通過css class屬性定位

4.2.3 元素選擇器

說明:根據元素標籤名來選擇 格式:element 如:input(選擇所有input元素)

elements = wd.find_elements(By.CSS_SELECTOR,('a'))#通過css 標籤名定位

4.2.4 屬性選擇器

說明:根據元素的屬性名和值來選擇 格式:[attribute=value] 如:[type=‘password’](選擇所有type屬性為password的值)

elements = wd.find_elements(By.CSS_SELECTOR,('[name="wd"]'))#通過css 屬性名與值判斷

4.2.5 層級選擇器

說明:根據元素的父子關係來選擇 格式:element>element 如:p>input(返還所有P元素下所有的input元素) 提示:>可以用空格代替,如:p input或者 p [type=‘password’]

elements = wd.find_elements(By.CSS_SELECTOR,('body div a'))

總結

以上呢就是本章所講的內容,可以自己嘗試編寫指令碼實現一些簡單的自動化操作,下一節將拓展selenium的具體用法,使之操作更加多樣化,複雜化。

Tide安全團隊正式成立於2019年1月,是新潮資訊旗下以網際網路攻防技術研究為目標的安全團隊,團隊致力於分享高質量原創文章、開源安全工具、交流安全技術,研究方向覆蓋網路攻防、系統安全、Web安全、移動終端、安全開發、物聯網/工控安全/AI安全等多個領域。

團隊作為“省級等保關鍵技術實驗室”先後與哈工大、齊魯銀行、聊城大學、交通學院等多個高校名企建立聯合技術實驗室,近三年來在網路安全技術方面開展研發專案60餘項,獲得各類自主智慧財產權30餘項,省市級科技專案立項20餘項,研究成果應用於產品核心技術研究、國家重點科技專案攻關、專業安全服務等。對安全感興趣的小夥伴可以加入或關注我們。