以下測試參考了下面幾本書 :
- Python 網路爬蟲實戰 (松崗, 胡松濤) 第 8 章
- Python 自動化的樂趣 (碁峰, AL Sweigart) 第 11 章
- Python 程式設計實務 (博碩, 何敏煌) 第 10-3 節
- Python 初學特訓班 (碁峰, 文淵閣工作室) 第 6-3, 6.4 節
- 不只是測試-Python 網路爬蟲王者 Slenium (佳魁, 蟲師) 第 4 章
- Learning Selenium Testing Tools With Python (Packt, Unmesh Gundecha) 第 4 章
# Python 學習筆記 : 安裝執行環境與 IDLE 基本操作
# Python 學習筆記 : 檔案處理
# Python 學習筆記 : 日誌 (logging) 模組測試
# Python 學習筆記 : 資料庫存取測試 (一) SQLite
# Python 學習筆記 : 資料庫存取測試 (二) MySQL
# Python 學習筆記 : Selenium 模組瀏覽器自動化測試 (一)
除了上列書籍外, 我還參考了下列 Selenium 教學網站 :
# Selenium with Python
# Free Selenium Tutorials
# Selenium Tutorial for Beginners
# https://www.tutorialspoint.com/selenium/index.htm
# Python 進階爬蟲
從前一篇測試可知 Chrome 的 Web Driver 安裝最沒問題, 所以以下測試是以 Chrome 為對象, 理論上 Selenium 的所有函數在所支援的瀏覽器都是通用的.
1. 取得瀏覽器物件之屬性 :
呼叫 webdriver.Chrome(), webdriver.Opera() 或 webdriver.Firfox() 等函數將傳回一個 WebDriver 物件 (瀏覽器物件), Selenium Webdriver API 在此物件中提供了許多屬性與方法以操控瀏覽器, 例如呼叫 get() 方法可在模擬瀏覽器中開啟指定網頁, 透過下列屬性可取得已開啟網頁之屬性 :
以開啟 "Webbots, Spiders and Screen Scrapers" 這本書的測試網頁 hello_world.html 為例 :
>>> from selenium import webdriver #匯入 webdriver 模組
>>> browser=webdriver.Chrome() #開啟模擬瀏覽器
>>> browser.get("http://www.webbotsspidersscreenscrapers.com/hello_world.html")
>>> browser.name #瀏覽器名稱
'chrome'
>>> browser.title #網頁標題
'Hello, world!'
>>> browser.current_url #網頁 URL
'http://www.webbotsspidersscreenscrapers.com/hello_world.html'
>>> browser.page_source #網頁原始碼
'<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><html xmlns="http://www.w3.org/1999/xhtml"><head>\n\t<title>Hello, world!</title>\n</head>\n\n<body>\nCongratulations! If you can read this, <br />\nyou successfully downloaded this file.\n\n\n</body></html>'
>>> browser.session_id #連線 ID
'ba0f0e4f432eb1a2f0280736f20f2825'
>>> browser.capabilities #瀏覽器功能設定
{'acceptInsecureCerts': False, 'acceptSslCerts': False, 'applicationCacheEnabled': False, 'browserConnectionEnabled': False, 'browserName': 'chrome', 'chrome': {'chromedriverVersion': '2.38.552522 (437e6fbedfa8762dec75e2c5b3ddb86763dc9dcb)', 'userDataDir': 'C:\\Users\\cht\\AppData\\Local\\Temp\\scoped_dir5572_4888'}, 'cssSelectorsEnabled': True, 'databaseEnabled': False, 'handlesAlerts': True, 'hasTouchScreen': False, 'javascriptEnabled': True, 'locationContextEnabled': True, 'mobileEmulationEnabled': False, 'nativeEvents': True, 'networkConnectionEnabled': False, 'pageLoadStrategy': 'normal', 'platform': 'Windows NT', 'rotatable': False, 'setWindowRect': True, 'takesHeapSnapshot': True, 'takesScreenshot': True, 'unexpectedAlertBehaviour': '', 'version': '66.0.3359.181', 'webStorageEnabled': True}
2. 操控瀏覽器之位置與大小 :
瀏覽器物件的下列方法可操控瀏覽器之位置與大小 :
例如 :
>>> browser.get_window_position()
{'x': 10, 'y': 10}
>>> browser.set_window_position(50, 100)
>>> browser.get_window_position()
{'x': 50, 'y': 100}
>>> browser.get_window_size()
{'width': 1050, 'height': 664}
>>> browser.set_window_size(1024, 768)
>>> browser.get_window_size()
{'width': 1024, 'height': 738}
>>> browser.maximize_window()
>>> browser.get_window_size()
{'width': 1296, 'height': 698}
>>> browser.minimize_window()
Traceback (most recent call last):
File "<pyshell#22>", line 1, in <module>
browser.minimize_window()
File "C:\Python36\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 740, in minimize_window
self.execute(Command.MINIMIZE_WINDOW)
File "C:\Python36\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 314, in execute
self.error_handler.check_response(response)
File "C:\Python36\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 208, in check_response
raise exception_class(value)
selenium.common.exceptions.WebDriverException: Message: unknown command: session/ba0f0e4f432eb1a2f0280736f20f2825/window/minimize
奇怪, 為何 minimize_window() 不動作呢? 錯誤訊息是 "unknown command", 難道 Chrome 沒有實作此方法? 搜尋網路發現有人也遇到此問題, 但看似無解, 參考 :
# Python Selenium浏览器最小化方法minimize_window(self)抛异常
我在下列文章看到模擬 minimize_window() 的方法 :
# Selenium Python minimize browser window
>>> browser.set_window_position(-3000, 0) #模擬視窗最小化
>>> browser.set_window_position(0, 0) #視窗復原
3. 操控瀏覽器按鈕 :
瀏覽器基本上有 "上一頁", "下一頁", "重新載入", 以及 "關閉" 四個按鈕, 可以透過瀏覽器物件的下列方法用程式操控 :
例如 :
>>> from selenium import webdriver #匯入 webdriver 模組
>>> browser=webdriver.Chrome() #開啟模擬瀏覽器
>>> urls=["http://www.google.com.tw", #URL 串列
"http://tw.yahoo.com",
"https://twitter.com"]
>>> for url in urls: #依序開啟網頁 (最後停在 Twitter)
browser.get(url)
>>> browser.current_url #最後停在 Twitter
'https://twitter.com/'
>>> browser.back() #回前一頁 (YAHOO)
>>> browser.current_url
'https://tw.yahoo.com/'
>>> browser.back() #回前一頁 (Google)
>>> browser.current_url
'https://www.google.com.tw/?gws_rd=ssl'
>>> browser.forward() #回後一頁 (YAHOO)
>>> browser.current_url
'https://tw.yahoo.com/'
>>> browser.forward() #回後一頁 (Twitter)
>>> browser.current_url
'https://twitter.com/'
>>> browser.refresh() #重新載入
上例依序開啟 Google, YAHOO, Twitter 三個網頁, 最後網頁是載入 Twitter. 透過呼叫 back(), forward() 來操控載入上一頁與下一頁動作, 並透過 cuurent_url 屬性來檢查是否載入正確網頁.
4. 儲存網頁快照 (screenshot) :
瀏覽器物件有一個 save_screenshot() 方法可將目前網頁儲存為 PNG 檔案下載至本機目錄下, 傳回值為 True 表示存檔成功, False 為失敗.
傳入參數若為單純檔名, 則 PNG 檔將儲存在 Python 安裝目錄下; 也可以傳入包含路徑之檔名, 這樣 PNG 檔就會存在指定目錄下, 但要注意在 Windows 下路徑分隔符是兩個倒斜線 (Escape), 例如 :
>>> from selenium import webdriver #匯入 webdriver 模組
>>> browser=webdriver.Chrome() #開啟模擬瀏覽器
>>> browser.get("http://tw.yahoo.com") #開啟 YAHOO
>>> browser.save_screenshot("yahoo.png") #儲存快照 PNG
True
>>> browser.save_screenshot("d:\Python\test\yahoo.png") #須雙倒斜線
False
>>> browser.save_screenshot("d:\\Python\\test\\yahoo.png") #指定路徑
True
注意, 所儲存是完整網頁的快照, 不受視窗大小的影響, 用 set_window_size()將瀏覽器視窗設成多小都能下載到完整網頁之快照.
5. 操控網頁元素 :
這部分就是 Selenium Webdriver 作為網路爬蟲的核心功能, 在上面的測試中利用 page_source 屬性可取得所開啟網頁之原始網頁 HTML 內容, Webdriver 本身自帶了許多方法可從 HTML 原始碼中擷取資訊, 不需要用到 BeautifulSoup. 此外, 還可以透過下列方法來取得網頁元素 (標籤 tag), 以便進行網頁操控.
呼叫 find_element_ 方法會傳回一個代表網頁元素的 WebElement 物件, 如果是呼叫 find_elements_ 方法則會傳回 WebElement 物件組成的串列. 此 WebElement 物件有如下屬性與方法可取得網頁元素的內容或對元素進行操控, 例如按下按鈕或填入資料等.
以 Invent With Python 網站首頁為例, 在 Chrome 按 F12 或按 Ctrl + U 開啟 "檢視網頁原始碼", 可知有一個 id 屬性值為 navbarSupportedContent 的 div 元素 :
<body style="background-color: #caeab7;">
<nav class="navbar navbar-toggleable-md">
<button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon text-white">☰</span>
</button>
<a class="navbar-brand" href="/">Invent with Python</a>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" id="navbarDropdownReadMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Read for Free
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdownReadMenuLink">
<a class="dropdown-item" href="https://automatetheboringstuff.com">Automate the Boring Stuff with Python</a>
<a class="dropdown-item" href="/cracking">Cracking Codes with Python</a>
<a class="dropdown-item" href="/invent4thed">Invent Your Own Computer Games with Python</a>
<a class="dropdown-item" href="/pygame">Making Games with Python & Pygame</a>
<a class="dropdown-item" href="https://inventwithscratch.com">Scratch Programming Playground</a>
</div>
</li>
.... (略)
<li class="nav-item">
<a class="nav-link" href="https://www.youtube.com/user/Albert10110">YouTube</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://www.reddit.com/r/inventwithpython">Forum</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/blog">Blog</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/#donate">Donate</a>
</li>
先利用 find_element_by_id() 方法取得此 div 元素之 WebElement 物件, 就可以用上表中的屬性與方法取得此標籤之內容, 例如 :
>>> from selenium import webdriver
>>> browser=webdriver.Chrome()
>>> browser.get("http://inventwithpython.com/")
>>> divEle=browser.find_element_by_id("navbarSupportedContent")
>>> type(divEle)
<class 'selenium.webdriver.remote.webelement.WebElement'>
>>> divEle.tag_name
'div'
>>> divEle.get_attribute("class")
'collapse navbar-collapse'
>>> divEle.location
{'x': 0, 'y': 0}
>>> divEle.text
''
以 id 搜尋理論上應該只找到一個 WebElement 物件, 若以 class 或 tag 等來尋找則會找到多個 WebElement 物件, 這時就會將這些物件放在 list 中傳回, 例如搜尋 class 屬性為 dropdown-item 的元素會找到具有此 class 之多個超連結 a, 這些 WebElement 物件會放在串列中傳回, 可以用 for in 來迭代顯示 a 元素中的 href 屬性 (即網址), 例如 :
>>> classEles=browser.find_elements_by_class_name("nav-link")
>>> for ele in classEles:
print(ele.get_attribute("href"))
None
None
None
https://www.youtube.com/user/Albert10110
https://www.reddit.com/r/inventwithpython
http://inventwithpython.com/blog
http://inventwithpython.com/#donate
從前一篇測試可知 Chrome 的 Web Driver 安裝最沒問題, 所以以下測試是以 Chrome 為對象, 理論上 Selenium 的所有函數在所支援的瀏覽器都是通用的.
1. 取得瀏覽器物件之屬性 :
呼叫 webdriver.Chrome(), webdriver.Opera() 或 webdriver.Firfox() 等函數將傳回一個 WebDriver 物件 (瀏覽器物件), Selenium Webdriver API 在此物件中提供了許多屬性與方法以操控瀏覽器, 例如呼叫 get() 方法可在模擬瀏覽器中開啟指定網頁, 透過下列屬性可取得已開啟網頁之屬性 :
屬性 | 說明 |
name | 瀏覽器名稱 |
title | 目前開啟網頁之標題 |
current_url | 目前開啟網頁之 URL |
page_source | 目前開啟網頁之原始碼 |
session_id | 網頁連線 id |
capabilities | 瀏覽器功能設定 |
以開啟 "Webbots, Spiders and Screen Scrapers" 這本書的測試網頁 hello_world.html 為例 :
>>> from selenium import webdriver #匯入 webdriver 模組
>>> browser=webdriver.Chrome() #開啟模擬瀏覽器
>>> browser.get("http://www.webbotsspidersscreenscrapers.com/hello_world.html")
>>> browser.name #瀏覽器名稱
'chrome'
>>> browser.title #網頁標題
'Hello, world!'
>>> browser.current_url #網頁 URL
'http://www.webbotsspidersscreenscrapers.com/hello_world.html'
>>> browser.page_source #網頁原始碼
'<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><html xmlns="http://www.w3.org/1999/xhtml"><head>\n\t<title>Hello, world!</title>\n</head>\n\n<body>\nCongratulations! If you can read this, <br />\nyou successfully downloaded this file.\n\n\n</body></html>'
>>> browser.session_id #連線 ID
'ba0f0e4f432eb1a2f0280736f20f2825'
>>> browser.capabilities #瀏覽器功能設定
{'acceptInsecureCerts': False, 'acceptSslCerts': False, 'applicationCacheEnabled': False, 'browserConnectionEnabled': False, 'browserName': 'chrome', 'chrome': {'chromedriverVersion': '2.38.552522 (437e6fbedfa8762dec75e2c5b3ddb86763dc9dcb)', 'userDataDir': 'C:\\Users\\cht\\AppData\\Local\\Temp\\scoped_dir5572_4888'}, 'cssSelectorsEnabled': True, 'databaseEnabled': False, 'handlesAlerts': True, 'hasTouchScreen': False, 'javascriptEnabled': True, 'locationContextEnabled': True, 'mobileEmulationEnabled': False, 'nativeEvents': True, 'networkConnectionEnabled': False, 'pageLoadStrategy': 'normal', 'platform': 'Windows NT', 'rotatable': False, 'setWindowRect': True, 'takesHeapSnapshot': True, 'takesScreenshot': True, 'unexpectedAlertBehaviour': '', 'version': '66.0.3359.181', 'webStorageEnabled': True}
2. 操控瀏覽器之位置與大小 :
瀏覽器物件的下列方法可操控瀏覽器之位置與大小 :
方法 | 說明 |
get_window_position() | 取得瀏覽器視窗左上角位置 |
set_window_position(x, y) | 設定瀏覽器視窗左上角位置 |
get_window_size() | 取得瀏覽器視窗大小 |
set_window_size(x, y) | 設定瀏覽器視窗大小 |
maximize_window() | 將瀏覽器視窗最大化 |
minimize_window() | 將瀏覽器視窗最小化 |
例如 :
>>> browser.get_window_position()
{'x': 10, 'y': 10}
>>> browser.set_window_position(50, 100)
>>> browser.get_window_position()
{'x': 50, 'y': 100}
>>> browser.get_window_size()
{'width': 1050, 'height': 664}
>>> browser.set_window_size(1024, 768)
>>> browser.get_window_size()
{'width': 1024, 'height': 738}
>>> browser.maximize_window()
>>> browser.get_window_size()
{'width': 1296, 'height': 698}
>>> browser.minimize_window()
Traceback (most recent call last):
File "<pyshell#22>", line 1, in <module>
browser.minimize_window()
File "C:\Python36\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 740, in minimize_window
self.execute(Command.MINIMIZE_WINDOW)
File "C:\Python36\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 314, in execute
self.error_handler.check_response(response)
File "C:\Python36\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 208, in check_response
raise exception_class(value)
selenium.common.exceptions.WebDriverException: Message: unknown command: session/ba0f0e4f432eb1a2f0280736f20f2825/window/minimize
奇怪, 為何 minimize_window() 不動作呢? 錯誤訊息是 "unknown command", 難道 Chrome 沒有實作此方法? 搜尋網路發現有人也遇到此問題, 但看似無解, 參考 :
# Python Selenium浏览器最小化方法minimize_window(self)抛异常
我在下列文章看到模擬 minimize_window() 的方法 :
# Selenium Python minimize browser window
>>> browser.set_window_position(-3000, 0) #模擬視窗最小化
>>> browser.set_window_position(0, 0) #視窗復原
3. 操控瀏覽器按鈕 :
瀏覽器基本上有 "上一頁", "下一頁", "重新載入", 以及 "關閉" 四個按鈕, 可以透過瀏覽器物件的下列方法用程式操控 :
方法 | 說明 |
back() | 按瀏覽器 "上一頁" 鈕 |
forward() | 按瀏覽器 "下一頁" 鈕 |
refresh() | 按瀏覽器 "更新" 鈕 |
quit() | 按瀏覽器 "關閉" 鈕, 同時關閉驅動程式 |
close() | 按瀏覽器 "關閉" 鈕 |
例如 :
>>> from selenium import webdriver #匯入 webdriver 模組
>>> browser=webdriver.Chrome() #開啟模擬瀏覽器
>>> urls=["http://www.google.com.tw", #URL 串列
"http://tw.yahoo.com",
"https://twitter.com"]
>>> for url in urls: #依序開啟網頁 (最後停在 Twitter)
browser.get(url)
>>> browser.current_url #最後停在 Twitter
'https://twitter.com/'
>>> browser.back() #回前一頁 (YAHOO)
>>> browser.current_url
'https://tw.yahoo.com/'
>>> browser.back() #回前一頁 (Google)
>>> browser.current_url
'https://www.google.com.tw/?gws_rd=ssl'
>>> browser.forward() #回後一頁 (YAHOO)
>>> browser.current_url
'https://tw.yahoo.com/'
>>> browser.forward() #回後一頁 (Twitter)
>>> browser.current_url
'https://twitter.com/'
>>> browser.refresh() #重新載入
上例依序開啟 Google, YAHOO, Twitter 三個網頁, 最後網頁是載入 Twitter. 透過呼叫 back(), forward() 來操控載入上一頁與下一頁動作, 並透過 cuurent_url 屬性來檢查是否載入正確網頁.
4. 儲存網頁快照 (screenshot) :
瀏覽器物件有一個 save_screenshot() 方法可將目前網頁儲存為 PNG 檔案下載至本機目錄下, 傳回值為 True 表示存檔成功, False 為失敗.
方法 | 說明 |
save_screenshot(filename) | 將目前網頁儲存為 png 檔案下載 |
傳入參數若為單純檔名, 則 PNG 檔將儲存在 Python 安裝目錄下; 也可以傳入包含路徑之檔名, 這樣 PNG 檔就會存在指定目錄下, 但要注意在 Windows 下路徑分隔符是兩個倒斜線 (Escape), 例如 :
>>> from selenium import webdriver #匯入 webdriver 模組
>>> browser=webdriver.Chrome() #開啟模擬瀏覽器
>>> browser.get("http://tw.yahoo.com") #開啟 YAHOO
>>> browser.save_screenshot("yahoo.png") #儲存快照 PNG
True
>>> browser.save_screenshot("d:\Python\test\yahoo.png") #須雙倒斜線
False
>>> browser.save_screenshot("d:\\Python\\test\\yahoo.png") #指定路徑
True
5. 操控網頁元素 :
這部分就是 Selenium Webdriver 作為網路爬蟲的核心功能, 在上面的測試中利用 page_source 屬性可取得所開啟網頁之原始網頁 HTML 內容, Webdriver 本身自帶了許多方法可從 HTML 原始碼中擷取資訊, 不需要用到 BeautifulSoup. 此外, 還可以透過下列方法來取得網頁元素 (標籤 tag), 以便進行網頁操控.
方法 | 說明 |
find_element(by, value) | 使用 by 指定之方法取得第一個符合 value 的元素 |
find_element_by_class_name(name) | 傳回符合指定 class 名稱之元素 |
find_elements_by_class_name(name) | 傳回符合指定 class 名稱之元素串列 |
find_element_by_css_selector(selector) | 傳回符合指定 CSS 選擇器名稱之元素 |
find_elements_by_css_selector(selector) | 傳回符合指定 CSS 選擇器名稱之元素串列 |
find_element_by_id(id) | 傳回符合指定 id 之元素 |
find_elements_by_id(id) | 傳回符合指定 id 之元素串列 |
find_element_by_link_text(text) | 傳回符合指定超連結文字之元素 |
find_elements_by_link_text(text) | 傳回符合指定超連結文字之元素串列 |
find_element_by_partial_link_text(text) | 傳回符合部分指定超連結文字之元素 |
find_elements_by_partial_link_text(text) | 傳回符合部分指定超連結文字之元素串列 |
find_element_by_name(name) | 傳回符合指定元素名稱之元素 |
find_elements_by_name(name) | 傳回符合指定元素名稱之元素串列 |
find_element_by_tag_name(tag) | 傳回符合指定標籤名稱之元素 |
find_elements_by_tag_name(tag) | 傳回符合指定標籤名稱之元素串列 |
呼叫 find_element_ 方法會傳回一個代表網頁元素的 WebElement 物件, 如果是呼叫 find_elements_ 方法則會傳回 WebElement 物件組成的串列. 此 WebElement 物件有如下屬性與方法可取得網頁元素的內容或對元素進行操控, 例如按下按鈕或填入資料等.
屬性或方法 | 說明 |
tag_name | 元素 (標籤) 名稱 |
location | 傳回元素對應螢幕左上角之座標 (x, y 字典) |
text | 開頭標籤與結尾標籤之間的文字 (即 innerText) |
get_attribute(attr) | 傳回屬性名稱 attr 之內容 |
click() | 觸發元素之 click 事件 (按鈕, 超連結, 表單提交等元素) |
send_keys(str) | 對元素傳送文字 str (文字欄位或文字區域 textarea 元素) |
clear() | 清除文字欄位或文字區域之內容 |
is_displayed() | 傳回 True (元素可見) 或 False (元素不可見) |
is_enabled() | 傳回 True (元素可用) 或 False (元素不可用) |
is_selected() | 傳回 True (元素有被勾選) 或 False (元素沒被勾選) : 核取方塊/選項圓鈕 |
以 Invent With Python 網站首頁為例, 在 Chrome 按 F12 或按 Ctrl + U 開啟 "檢視網頁原始碼", 可知有一個 id 屬性值為 navbarSupportedContent 的 div 元素 :
<body style="background-color: #caeab7;">
<nav class="navbar navbar-toggleable-md">
<button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon text-white">☰</span>
</button>
<a class="navbar-brand" href="/">Invent with Python</a>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" id="navbarDropdownReadMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Read for Free
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdownReadMenuLink">
<a class="dropdown-item" href="https://automatetheboringstuff.com">Automate the Boring Stuff with Python</a>
<a class="dropdown-item" href="/cracking">Cracking Codes with Python</a>
<a class="dropdown-item" href="/invent4thed">Invent Your Own Computer Games with Python</a>
<a class="dropdown-item" href="/pygame">Making Games with Python & Pygame</a>
<a class="dropdown-item" href="https://inventwithscratch.com">Scratch Programming Playground</a>
</div>
</li>
.... (略)
<li class="nav-item">
<a class="nav-link" href="https://www.youtube.com/user/Albert10110">YouTube</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://www.reddit.com/r/inventwithpython">Forum</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/blog">Blog</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/#donate">Donate</a>
</li>
先利用 find_element_by_id() 方法取得此 div 元素之 WebElement 物件, 就可以用上表中的屬性與方法取得此標籤之內容, 例如 :
>>> from selenium import webdriver
>>> browser=webdriver.Chrome()
>>> browser.get("http://inventwithpython.com/")
>>> divEle=browser.find_element_by_id("navbarSupportedContent")
>>> type(divEle)
<class 'selenium.webdriver.remote.webelement.WebElement'>
>>> divEle.tag_name
'div'
>>> divEle.get_attribute("class")
'collapse navbar-collapse'
>>> divEle.location
{'x': 0, 'y': 0}
>>> divEle.text
''
以 id 搜尋理論上應該只找到一個 WebElement 物件, 若以 class 或 tag 等來尋找則會找到多個 WebElement 物件, 這時就會將這些物件放在 list 中傳回, 例如搜尋 class 屬性為 dropdown-item 的元素會找到具有此 class 之多個超連結 a, 這些 WebElement 物件會放在串列中傳回, 可以用 for in 來迭代顯示 a 元素中的 href 屬性 (即網址), 例如 :
>>> classEles=browser.find_elements_by_class_name("nav-link")
>>> for ele in classEles:
print(ele.get_attribute("href"))
None
None
None
https://www.youtube.com/user/Albert10110
https://www.reddit.com/r/inventwithpython
http://inventwithpython.com/blog
http://inventwithpython.com/#donate
前三個 None 是因為找到三個 class="nav-link dropdown-toggle" 的無 href 屬性之 a 元素之故.
沒有留言:
張貼留言