前面咱們學習了根據 id、class屬性、tag名選擇元素。css
若是咱們要選擇的元素沒有id、class 屬性,或者有些咱們不想選擇的元素也有相同的id、class屬性值,怎麼辦呢?html
這時候咱們一般能夠經過CSS selector語法選擇元素。web
HTML中常常要爲某些元素指定顯示效果,好比前景文字顏色是紅色,背景顏色是黑色,字體是微軟雅黑等。chrome
那麼CSS必須告訴瀏覽器:要選擇哪些元素,來使用這樣的顯示風格。編程
好比,下圖中,爲何灰太狼紅太狼小灰灰會顯示爲紅色呢?瀏覽器
html代碼:工具
<head> <meta charset="UTF-8"> <title></title> <style type="text/css"> .wolf{ color: red; } </style> </head> <body> <div class="raise"><span>喜羊羊</span></div> <div class="raise"><span>美羊羊</span></div> <div class="raise"><span>暖羊羊</span></div> <div class="wolf"><span>灰太狼</span></div> <div class="wolf"><span>紅太狼</span></div> <div class="wolf"><span>小灰灰</span></div> </body>
由於藍色框裏面用css 樣式,指定了class值爲wolf的元素,要顯示爲紅色。學習
其中藍色框裏面的.wolf就是CSS Selector,或者說CSS選擇器。字體
CSS Selector語法就是用來選擇元素的。網站
既然CSS Selector語法天生就是瀏覽器用來選擇元素的,selenium天然就可使用它用在自動化中,去選擇要操做的元素了。
只要CSS Selector的語法是正確的,Selenium就能夠選擇到該元素。
CSS Selector很是強大,學習Selenium Web自動化必定要學習CSS Selector。
經過CSS Selector選擇單個元素的方法是:
find_element_by_css_selector(CSS Selector參數)
選擇全部元素的方法是:
find_elements_by_css_selector(CSS Selector參數)
CSS Selector選擇元素很是靈活強大,你們能夠從下面的例子看出來。
CSS Selector一樣能夠根據tag名、id 屬性和class屬性來選擇元素。
根據tag名選擇元素的CSS Selector語法很是簡單,直接寫上tag名便可。
好比要選擇全部的tag名爲div的元素,就能夠是這樣:
elements = wd.find_elements_by_css_selector('div')
等價於
elements = wd.find_elements_by_tag_name('div')
根據id屬性選擇元素的語法是在id號前面加上一個井號:#id值
下面這樣的元素:
<input type="text" id='searchtext' />
就可使用#searchtext這樣的CSS Selector來選擇它。
好比,咱們想在id爲searchtext的輸入框中輸入文本 你好,完整的Python代碼以下:
from selenium import webdriver wd = webdriver.Chrome(r'E:\webdrivers\chromedriver.exe') wd.get('http://127.0.0.1:8020/day01/index.html') element = wd.find_element_by_css_selector('#searchtext') element.send_keys('你好')
根據class屬性 選擇元素的語法是在 class 值 前面加上一個點:.class值
要選擇全部class屬性值爲wolf的元素狼除了這樣寫:
elements = wd.find_elements_by_class_name('wolf')
還能夠這樣寫:
elements = wd.find_elements_by_css_selector('.wolf')
由於是選擇全部符合條件的,因此用find_elements而不是find_element。
HTML中,元素內部能夠包含其餘元素,好比下面的 HTML片斷:
<div id='container'> <div id='layer1'> <div id='inner11'> <span>內層11</span> </div> <div id='inner12'> <span>內層12</span> </div> </div> <div id='layer2'> <div id='inner21'> <span>內層21</span> </div> </div> </div>
下面的一段話有些繞口,請你們細心閱讀:
id爲container的div元素包含了id爲layer1和layer2的兩個div元素。
這種包含是直接包含,中間沒有其餘的層次的元素了。 因此id爲layer1和layer2的兩個div元素是id爲container的div元素的直接子元素。
而id爲layer1的div元素又包含了id爲inner11和inner12的兩個div元素。其中沒有其餘層次的元素,全部這種包含關係也是直接子元素關係。
id爲layer2的div元素又包含了id爲inner21這個div元素。這種包含關係也是直接子元素關係。
而對於id爲container的div元素來講,id爲inner十一、inner十二、inner22的元素和兩個span類型的元素都不是它的直接子元素,由於中間隔了幾層。
雖然不是直接子元素,可是它們仍是在container的內部,能夠稱之爲它的後代元素。
後代元素也包括了直接子元素,好比id爲layer1和layer2的兩個div元素,也能夠說是id爲container的div元素的直接子元素,同時也是後代子元素。
若是元素2是元素1的直接子元素,CSS Selector選擇子元素的語法是這樣的:
元素1 > 元素2
中間用一個大於號(咱們能夠理解爲箭頭號)
注意,最終選擇的元素是元素2,而且要求這個元素2是元素1的直接子元素。
也支持更多層級的選擇,好比:
元素1 > 元素2 > 元素3 > 元素4
就是選擇元素1裏面的子元素元素2裏面的子元素元素3裏面的子元素元素4,最終選擇的元素是元素4。
若是元素2是元素1的後代元素,CSS Selector選擇後代元素的語法是這樣的:
元素1 元素2
中間是一個或者多個空格隔開
最終選擇的元素是元素2,而且要求這個元素2是元素1的後代元素。
也支持更多層級的選擇,好比:
元素1 元素2 元素3 元素4
最終選擇的元素是元素4.
id、class 都是web元素的屬性,由於它們是很經常使用的屬性,因此css選擇器專門提供了根據 id、class 選擇的語法。
那麼其餘的屬性呢?
好比
<a href="https://www.cnblogs.com/liuhui0308/">愛編程的小灰灰</a>
裏面根據href選擇,能夠用css選擇器嗎?
固然能夠!
css選擇器支持經過任何屬性來選擇元素,語法是用一個方括號[]。
好比要選擇上面的a元素,就可使用
[href="https://www.cnblogs.com/liuhui0308/"]
這個表達式的意思是,選擇屬性href值爲https://www.cnblogs.com/liuhui0308/的元素。
完整代碼以下:
from selenium import webdriver wd = webdriver.Chrome(r'E:\webdrivers\chromedriver.exe') wd.get('http://127.0.0.1:8020/day01/index.html') # 根據屬性選擇元素 element = wd.find_element_by_css_selector('[href="https://www.cnblogs.com/liuhui0308/"]') # 打印出元素對應的html print(element.get_attribute('outerHTML'))
固然,前面能夠加上標籤名的限制,好比div[class='SKnet'],表示選擇全部標籤名爲div,且class屬性值爲SKnet的元素。
屬性值用單引號,雙引號均可以。
根據屬性選擇,還能夠不指定屬性值,好比[href],表示選擇全部具備屬性名爲href的元素,無論它們的值是什麼。
CSS還能夠選擇屬性值包含某個字符串的元素。
好比,要選擇a節點,裏面的href屬性包含了miitbeian字符串,就能夠這樣寫:
a[href*="miitbeian"]
還能夠選擇屬性值以某個字符串開頭的元素
好比,要選擇a節點,裏面的href屬性以http開頭,就能夠這樣寫:
a[href^="http"]
還能夠選擇 屬性值以某個字符串結尾的元素
好比,要選擇a節點,裏面的href屬性以gov.cn 結尾,就能夠這樣寫:
a[href$="gov.cn"]
若是一個元素具備多個屬性:
<div class="misc" ctype="gun">沙漠之鷹</div>
CSS選擇器能夠指定選擇的元素要同時具備多個屬性的限制,像這樣
div[class=misc][ctype=gun]
那麼咱們怎麼驗證CSS Selector的語法是否正確選擇了咱們要選擇的元素呢?
固然能夠像下面這樣,寫出Python代碼,運行看看,可否操做成功。
element = wd.find_element_by_css_selector('#searchtext') element.input('輸入的文本')
若是成功,說明選擇元素的語法是正確的。
可是這樣作太麻煩了,浪費了不少的時間。
當咱們進行自動化開發的時候,有大量選擇元素的語句,都要這樣一個個的驗證,就很是浪費時間。
因爲CSS Selector是瀏覽器直接支持的,能夠在瀏覽器開發者工具欄中驗證。
咱們能夠打開一個網站,按F12打開開發者工具欄。
若是咱們要驗證下面的表達式
#bottom > .footer2 a
可否選中這個元素
<a href="https://www.cnblogs.com/liuhui0308/">愛編程的小灰灰</a>
html代碼:
<div id='bottom'> <div class='footer1'> <span class='copyright'>版權</span> <span class='date'>發佈日期:2019-11-26</span> </div> <div class='footer2'> <span>主頁 <a href="https://www.cnblogs.com/liuhui0308/">愛編程的小灰灰</a> </span> </div> </div>
能夠這樣作:
點擊Elements標籤後,同時按Ctrl鍵和F鍵,就會出現下圖箭頭處的搜索框:
咱們能夠在裏面輸入任何CSS Selector表達式,若是能選擇到元素,右邊的的紅色方框裏面就會顯示出相似1 of 1這樣的內容。
of後面的數字表示這樣的表達式總共選擇到幾個元素
of前面的數字表示當前黃色高亮顯示的是其中第幾個元素
上圖中的1 of 1 就是指:CSS選擇語法 #bottom > .footer2 a在當前網頁上共選擇到一個元素,沒錢高亮顯示的是第1個。
若是咱們輸入span就會發現,能夠選擇到3個元素