code:
# -*- coding: utf-8 -*-
"""
Created on Sun Feb 4 10:35:36 2024
@author: SavingKing
"""
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.chrome.options import Options
import os
import json
from typing import List
option = webdriver.ChromeOptions()
prefs = {"profile.default_content_setting_values":{"notifications":2}}
option.add_experimental_option("prefs",prefs)
driver = webdriver.Chrome(options=option)
#selenium.webdriver.chrome.webdriver.WebDriver
url = "https://ojt.wda.gov.tw/ClassSearch"
driver.get(url)
產業人才投資方案 = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable(
(By.CSS_SELECTOR, 'input[id="Form_PlanType_1"]')
)
)
產業人才投資方案.click()
#driver.find_element(By.CSS_SELECTOR,'input#Form_PlanType_1').click()
#driver.find_element(By.CSS_SELECTOR,'#Form_PlanType_1').click()
# driver.find_element(By.CSS_SELECTOR,'input[type="radio"]').click()
# driver.find_element(By.CSS_SELECTOR,'input[id="Form_PlanType_1"]').click()
關鍵字搜尋=driver.find_element(By.CSS_SELECTOR,"#Form_KEYWORDS").send_keys("大數據")
"""關鍵字搜尋:
<input class="form-control" id="Form_KEYWORDS" maxlength="100" name="Form.KEYWORDS" placeholder="請輸入關鍵字" title="請輸入關鍵字搜尋" type="text" value="">
送出:
<button type="submit" class="btn-orange" title="送出">送出</button>
"""
送出=driver.find_element(By.CSS_SELECTOR,".btn-orange").click()
#'button[title="送出"]'
webdriver.ActionChains(driver).send_keys(Keys.ESCAPE).perform()
執行結果:
webdriver.ActionChains(driver).send_keys(Keys.ESCAPE).perform()
是Selenium WebDriver中的一段代碼,它使用了ActionChains來模擬鍵盤操作。這行代碼的作用是向瀏覽器發送一個ESCAPE
鍵的按鍵事件。
以下是對這行代碼的逐部分解釋:
webdriver.ActionChains(driver)
:這部分創建了一個ActionChains對象。ActionChains是Selenium的一個工具,用於生成一系列複雜的動作,如鼠標操作和鍵盤操作。這裡它被初始化並與特定的WebDriver實例driver
關聯起來,這樣它就可以在該WebDriver打開的網頁上執行動作。.send_keys(Keys.ESCAPE)
:send_keys
方法用於模擬鍵盤輸入。Keys.ESCAPE
是Selenium提供的一個特殊鍵值,代表鍵盤上的Esc
鍵。這個方法的作用是將Esc
鍵的按鍵事件加入到動作鏈中。.perform()
:這是ActionChains的一個方法,用於執行先前添加到ActionChains的所有動作。在這個例子中,它將執行發送Esc
鍵的操作。當你使用 Selenium WebDriver 的 ActionChains 類來創建一系列動作時,你需要調用 .perform() 方法來執行這些動作。ActionChains 類是用來生成一個動作隊列的,這些動作可以包括鼠標操作(如點擊、拖動)、鍵盤操作(如按鍵輸入)或者這兩者的組合。這些動作被存儲在 ActionChains 對象中,直到你調用 .perform() 方法,這些動作才會被實際執行。如果你構建了一個動作鏈但忘記調用 .perform(),那麽這些動作將不會被執行,也就是說它們只會被添加到隊列中但不會應用到網頁上。
整行代碼的作用是在當前瀏覽器窗口中模擬按下Esc
鍵。這在自動化測試中非常有用,特別是當需要關閉彈出的對話框或取消某些正在進行的操作時。使用Esc
鍵的模擬按鍵事件是一種常見的方式來處理這類情況。
ActionChains在Selenium中是用於創建一系列動作(Action)的鏈式操作的意思。它允許你將多個動作組合在一起,形成一個動作序列,然後一次性執行這個序列中的所有動作。這種機制非常適合執行需要多步驟操作的交互,例如鼠標拖拽、長按、連續點擊等覆雜的用戶界面操作。
使用ActionChains的優勢:
靈活性:可以靈活地組合多種操作,包括鍵盤和鼠標操作,以模擬用戶的實際操作過程。
準確性:通過精確地控制操作的順序,能夠更準確地模擬用戶行為。
易讀性:鏈式操作的寫法使得代碼更加直觀易讀,便於理解每一步操作的邏輯。
推薦hahow線上學習python: https://igrape.net/30afN
#是id選擇器:
關鍵字搜尋=driver.find_element(By.CSS_SELECTOR,"#Form_KEYWORDS").send_keys("大數據")
等效於
關鍵字搜尋=driver.find_element(By.CSS_SELECTOR, '[id="Form_KEYWORDS"]').send_keys("大數據")
.是類別選擇器:
送出=driver.find_element(By.CSS_SELECTOR,".btn-orange").click()
等效於:
送出=driver.find_element(By.CSS_SELECTOR, '[class="btn-orange"]').click()
在使用CSS選擇器定位網頁元素時,.btn-orange和#Form_KEYWORDS是兩種常見的選擇器語法,用於指定元素的class和id屬性。讓我為您進一步明確這兩種選擇器的含義和用法:
“.btn-orange”:類選擇器
語法:.類名稱
用途:用於選擇頁面上所有具有指定class屬性的元素。當元素的class屬性中包含了指定的類名時,該元素會被選中。
示例:’.btn-orange’
等效於HTML中的:'[class=“btn-orange”]’(這意味著,任何的標簽都會被選中)。
解釋:在您提供的示例中,.btn-orange選擇器用於找到所有class屬性包含”btn-orange”的元素。如果有一個按鈕定義為送出,使用.btn-orange選擇器就可以定位到這個按鈕。
“#Form_KEYWORDS”:ID選擇器
語法:#ID名稱
用途:用於選擇頁面上具有指定id屬性的唯一元素。id屬性在HTML文檔中應該是唯一的,意味著每個id值只能被賦予給一個元素。
示例:’#Form_KEYWORDS’
等效於HTML中的:‘[id=“Form_KEYWORDS”]’(這意味著,任何的標簽都會被選中)。
解釋:在您提供的示例中,#Form_KEYWORDS選擇器用於找到id屬性值為”Form_KEYWORDS”的元素。如果有一個輸入框定義為,使用#Form_KEYWORDS選擇器就可以定位到這個輸入框。
總結
“.btn-orange” 用於選擇所有class屬性包含btn-orange值的元素,適用於類選擇器。
“#Form_KEYWORDS” 用於選擇id屬性值精確匹配Form_KEYWORDS的唯一元素,適用於ID選擇器。
通過這些選擇器,Selenium可以非常精確地在覆雜的網頁中定位元素,進行進一步的操作,如點擊、輸入文本等。
推薦hahow線上學習python: https://igrape.net/30afN
結合BeautifulSoupsoup = BeautifulSoup(driver.page_source,"html.parser")
這行代碼使用了BeautifulSoup庫來解析通過Selenium WebDriver獲取的網頁源代碼。BeautifulSoup是一個Python庫,廣泛用於web scraping(網頁抓取),能夠從HTML或XML文件中提取數據。這里的用法是一個很典型的示例,展示了如何結合使用BeautifulSoup和Selenium來處理動態網頁內容
driver.page_source:這部分是Selenium WebDriver的屬性,用於獲取當前瀏覽器窗口中顯示的頁面的源代碼。driver是Selenium WebDriver的一個實例,它控制著一個瀏覽器窗口。
BeautifulSoup(driver.page_source, “html.parser”):這是BeautifulSoup構造函數的調用,它接受兩個參數:
第一個參數是HTML文檔的字符串,這里使用driver.page_source獲取。
第二個參數是解析器的名稱,這里使用的是Python標準庫中的”html.parser”。BeautifulSoup還支持其他的解析器,如”lxml”和”html5lib”,每個解析器有其特點和使用場景。
soup:這個變量現在包含了一個BeautifulSoup對象,它表示了網頁的解析樹。通過這個對象,你可以使用BeautifulSoup提供的豐富接口來查詢和操作網頁元素。
推薦hahow線上學習python: https://igrape.net/30afN
code:
# -*- coding: utf-8 -*-
"""
Created on Sun Feb 4 10:35:36 2024
@author: SavingKing
"""
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.chrome.options import Options
import os
import json
from typing import List
option = webdriver.ChromeOptions()
prefs = {"profile.default_content_setting_values":{"notifications":2}}
option.add_experimental_option("prefs",prefs)
driver = webdriver.Chrome(options=option)
#selenium.webdriver.chrome.webdriver.WebDriver
url = "https://ojt.wda.gov.tw/ClassSearch"
driver.get(url)
產業人才投資方案 = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable(
(By.CSS_SELECTOR, 'input[id="Form_PlanType_1"]')
)
)
產業人才投資方案.click()
#driver.find_element(By.CSS_SELECTOR,'#Form_PlanType_1').click()
# driver.find_element(By.CSS_SELECTOR,'input[type="radio"]').click()
# driver.find_element(By.CSS_SELECTOR,'input[id="Form_PlanType_1"]').click()
關鍵字搜尋=driver.find_element(By.CSS_SELECTOR,"#Form_KEYWORDS").send_keys("python")
"""關鍵字搜尋:
<input class="form-control" id="Form_KEYWORDS" maxlength="100" name="Form.KEYWORDS" placeholder="請輸入關鍵字" title="請輸入關鍵字搜尋" type="text" value="">
送出:
<button type="submit" class="btn-orange" title="送出">送出</button>
"""
# tup=By.CSS_SELECTOR,".btn-orange"
# 送出=driver.find_element(tup).click() #不能用tup當參數
#InvalidArgumentException: invalid argument: 'using' must be a string
# (Session info: chrome=121.0.6167.161)
送出=driver.find_element(By.CSS_SELECTOR,".btn-orange").click()
#'button[title="送出"]'
webdriver.ActionChains(driver).send_keys(Keys.ESCAPE).perform()
from bs4 import BeautifulSoup
import time
soup = BeautifulSoup(driver.page_source,"html.parser")
# print(type(driver.page_source))
#bs4.BeautifulSoup
#driver.page_source <class 'str'>
#以前是用request.get()
def soup2lis_class(soup):
#resultset= soup.find_all('td',style="text-align:left")
resultset = soup.select('td[style="text-align:left"][headers="tb1-b"]')
"""
#bs4.element.ResultSet #len :10
<td style="text-align:left" headers="tb1-b">
<a title="AI 機器學習與大數據應用分析Python / R 雙語言進階班第01期
(東海大學)" href="javascript:doDetail('1','N','150122');">AI 機器學習與大數據應用分析Python / R 雙語言進階班第01期
(東海大學)</a>
<a title="AI 機器學習與大數據應用分析Python / R 雙語言進階班第01期
(東海大學)" href="/ClassSearch/Detail?PlanType=1&OCID=150122" target="_blank">●「另開新視窗」</a>
</td>
<td align="center" headers="tb1-g">
<div>(學) 臺北市</div> <div>(術) 臺北市</div> <div>(整班為實體教學)</div> </td>
"""
resultset1 = soup.select('td[align="center"][headers="tb1-g"]')
lis_class = []
for tag,tag1 in zip(resultset,resultset1):
#tag = resultset[0]
#bs4.element.Tag
text = tag.a.text
text1= tag1.div.text
lis_class.append((text,text1))
#一頁的十筆資料
return lis_class
lis_class_all=[]
while soup.find("a",id="nextPage")["class"] != ["disabled"]:
lis_class = soup2lis_class(soup)
lis_class_all.extend(lis_class)
next_page_button = driver.find_element(
By.CSS_SELECTOR,'a[id="nextPage"]'
)
#selenium.webdriver.remote.webelement.WebElement
next_page_button.click()
#WebDriverWait(driver, 10).until(EC.staleness_of(next_page_button))
time.sleep(5)
soup = BeautifulSoup(driver.page_source,"html.parser")
# if soup.find("a",id="nextPage")["class"] == ["disabled"]:
# break
"""最後一頁 class="disabled"
<a id="nextPage" href="javascript:nextPage()" class="disabled" title="往下一頁">下一頁</a>
"""
for ele in lis_class_all:
print(ele)
輸出結果:
推薦hahow線上學習python: https://igrape.net/30afN
近期留言