Selenium XPath

一、selenium是什麼呢?

selenium最初是一個自動化測試工具,而爬蟲中使用它主要是爲了解決requests沒法執行javaScript代碼的問題。css

它能夠作什麼呢?它能夠用幾行代碼,控制瀏覽器,作出自動打開、輸入、點擊等操做,就像是有一個真正的用戶在操做同樣。html

selenium容許讓人去手動輸入驗證碼,而後把剩下的操做交給機器。 而對於那些交互複雜、加密複雜的網站,selenium問題簡化 ,爬動態網頁如爬靜態網頁同樣簡單。java

安裝

pip install selenium # Windows電腦安裝selenium

selenium的腳本能夠控制全部常見瀏覽器的操做,在使用以前,須要安裝瀏覽器的驅動。python

我推薦的是Chrome瀏覽器,打開下面的連接,就能夠下載Chrome的安裝包了,Windows和Mac都有。jquery

國內鏡像網站地址:
        http://npm.taobao.org/mirrors/chromedriver/2.38/

設置瀏覽器引擎

下載chromed瀏覽器驅動:
    把下載好的chromedriver.exe放到python安裝路徑的scripts目錄中便可,注意最新版本是2.38,並不是2.9

和之前同樣,使用一個新的Python庫,首先要調用它。selenium有點不一樣,除了調用,還須要設置瀏覽器引擎。web

#本地Chrome瀏覽器設置方法
from selenium import webdriver  # 從selenium庫中調用webdriver庫
driver_path = r'E:\chromedriver_win32\chromedriver.exe'
driver = webdriver.Chrome(executable_path=driver_path)
#設置引擎爲Chrome,真實地打開一個Chrome瀏覽器

二、基本使用

示例一:
from selenium import webdriver  #用來驅動瀏覽器的
from selenium.webdriver import ActionChains #破解滑動驗證碼的時候用,可拖動圖片
from selenium.webdriver.common.by import By #按照什麼方式查找,By.ID,By.CSS_SELECTOR
from selenium.webdriver.common.keys import Keys #鍵盤按鍵操做
from selenium.webdriver.support import expected_conditions as EC        # 和下面WebDriverWait一塊兒用的
from selenium.webdriver.support.wait import WebDriverWait   #等待頁面加載某些元素
import time
try:
    driver = webdriver.Chrome()
    driver.get('https://www.baidu.com')
    wait = WebDriverWait(driver,10)
    input_tag = wait.until(EC.presence_of_element_located((By.ID,'kw')))
    input_tag.send_keys('美女')
    input_tag.send_keys(Keys.ENTER)
    time.sleep(5)

finally:
    driver.close()
示例二:

from selenium import webdriver  # 用來驅動瀏覽器的
from selenium.webdriver.common.by import By  # 按照什麼方式查找,By.ID,By.CSS_SELECTOR
from selenium.webdriver.support import expected_conditions as EC  # 和下面WebDriverWait一塊兒用的
from selenium.webdriver.support.wait import WebDriverWait  # 等待頁面加載某些元素
import time
option = webdriver.ChromeOptions()

# 經過add_argument爲配置添加參數
# 此參數用於跳過 "正受到自動測試軟件的控制"
option.add_argument('disable-infobars')

driver = webdriver.Chrome(chrome_options=option)

try:
    driver.get('https://china.nba.com/')    # 往NBA官網發送get請求
    wait = WebDriverWait(driver,10)         # 獲取等待對象,可等待某個元素10秒
    game = wait.until(EC.presence_of_element_located((By.CLASS_NAME,'nav-schedule')))
# 查找賽程標籤並點擊
    game.click()
    time.sleep(10)
except:
    driver.close()

三、等待元素被加載

'''
一、selenium只是模擬瀏覽器的行爲,而瀏覽器解析頁面是須要時間的(執行css,js),一些元素可能須要過一段時間才能加載出來,爲了保證全部元素都能查到,必須等待。

二、等待的方式分兩種:

    隱式等待:在browser.get('xxx')前就設置,針對全部元素有效

    顯式等待:在browser.get('xxx')以後設置,只針對某個元素有效
'''
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By #按照什麼方式查找,By.ID,By.CSS_SELECTOR
from selenium.webdriver.common.keys import Keys #鍵盤按鍵操做
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait #等待頁面加載某些元素

browser=webdriver.Chrome()

#隱式等待:在查找全部元素時,若是還沒有被加載,則等10秒
browser.implicitly_wait(10)

browser.get('https://www.baidu.com')


input_tag=browser.find_element_by_id('kw')
input_tag.send_keys('美女')
input_tag.send_keys(Keys.ENTER)

contents=browser.find_element_by_id('content_left') #沒有等待環節而直接查找,找不到則會報錯
print(contents)

browser.close()
 
隱式等待

from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By #按照什麼方式查找,By.ID,By.CSS_SELECTOR
from selenium.webdriver.common.keys import Keys #鍵盤按鍵操做
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait #等待頁面加載某些元素

browser=webdriver.Chrome()
browser.get('https://www.baidu.com')


input_tag=browser.find_element_by_id('kw')
input_tag.send_keys('美女')
input_tag.send_keys(Keys.ENTER)


#顯式等待:顯式地等待某個元素被加載
wait=WebDriverWait(browser,10)
wait.until(EC.presence_of_element_located((By.ID,'content_left')))

contents=browser.find_element(By.CSS_SELECTOR,'#content_left')
print(contents)


browser.close()

顯式等待

四、選擇器

  1. element和elements
element是查找一個標籤
elements是查找全部標籤

二、 find_element_by_tag_name

<img><a><P>chrome

此方式能夠經過 元素的標籤名稱 來查找元素,可是通常WEB網站的標籤名都是會重複的全部用的並不太方便。npm

三、 find_element_by_class_name

經過元素的class屬性選擇windows

四、 find_element_by_css_selector

(.)表示經過 class 屬性來定位元素

find_element_by_css_selector(h1.importane)
#獲取全部class值important的h1標籤

(#)表示經過 id 屬性來定位元素

<p id="intro">This is a paragraph of introduction.</p>

find_element_by_css_selector(#"intro")

經過屬性選擇器

<a title="W3School Home" href="http://w3school.com.cn">W3School</a>

find_element_by_css_selector('a[title][href]')

經過後代選擇器

#choose_car option    含空格的,後面的元素沒必要是前面元素的直接子元素,只要在父元素的裏面
#choose_car > option  含>鍵的,    後面的元素必須是前面元素的直接子元素
#ul > ol > li > em                能夠是不少級的父子關係

經過組合型

#food  > span , p                  選擇id 爲food的全部span子元素和全部的p(包括非food的子元素)
#food > span , #food > p            選擇id爲food的全部span子元素和全部p子元素
#food  > *                                 選擇id爲food的全部子元素

兄弟節點的選擇(平級關係)

#food + div      只選擇id爲food緊跟後面的div
#food ~div       選擇id爲food後面的div或div們,只須要在id的後面,不須要緊跟
方法二  根據元素的屬性及屬性值來選擇元素 :

*[style]  選擇全部有stype屬性的元素

p[spec=len2]   選擇spec屬性值只等於len2的p元素

yp[spec='len2 len3' ]    選擇spec屬性值只等於len2 len3的p元素   有空的值必定要加引號

p[spec*='len2']             選擇spec屬性值包含len2的p元素

p[spec^='len2']            選擇spec屬性值以len2開頭的p元素

p[spec&='len2']           選擇spec屬性值以len2結尾的p元素

p[class=special][name=p1]    選擇class值等於special,而且name值等於p1的p元素

p:nth-child(1)              選擇第一個p元素

p:nth-last-child(1)              選擇倒數第一個p元素(要保證最後一個元素是p)

五、find_element_by_id

經過元素id選擇

六、find_element_by_link_text

經過連接文本多去超連接

七、find_element_by_partial_link_text

經過連接的部分文本獲取超連接

八、find_element_by_name

經過元素的name屬性選擇

from selenium import webdriver
from selenium.webdriver import ActionChains
import time

option = webdriver.ChromeOptions()

option.add_argument('disable-infobars')

# 經過add_argument爲配置添加參數
# 此參數用於跳過 "正受到自動測試軟件的控制"
driver = webdriver.Chrome(chrome_options=option)

driver.get('https://qzone.qq.com/')
driver.implicitly_wait(10)

# 一、find_element_by_link_text  經過全局文本去找
driver.switch_to.frame('login_frame')
login_clike = driver.find_element_by_link_text('賬號密碼登陸').click()

# 二、find_element_by_id 經過id去找
user = driver.find_element_by_id('u')
user.send_keys('1394551891')
pwd = driver.find_element_by_id('p')
pwd.send_keys('zxczxc')

# 三、find_element_by_class_name  根據屬性名查找
login = driver.find_element_by_class_name('btn').click()

# 讓光標懸浮在我的中心
action = ActionChains(driver).move_to_element(driver.find_element_by_id('slideBlock')).perform()


# 四、find_element_by_partial_link_text  經過局部文本去找
login_tag = driver.find_element_by_partial_link_text('登')
login_tag.click()

# 六、find_element_by_css_selector 根據屬性選擇器查找
login_btn = driver.find_element_by_css_selector('.btn-login')
login_btn.click()

# 七、find_element_by_tag_name  根據標籤名查找
a_s = driver.find_elements_by_tag_name('a')
    for a in a_s:
        # 打印字數超過10位的文本
        if len(a.text) > 10:
            print(a.tex

九、find_element_by_xpath("xpath")

XPath 是一門在 XML 文檔中查找信息的語言。XPath 用於在 XML 文檔中經過元素和屬性進行查找。

在 XPath 中,有七種類型的節點:元素、屬性、文本、命名空間、處理指令、註釋以及文檔(根)節點。XML 文檔是被做爲節點樹來對待的。樹的根被稱爲文檔節點或者根節點。

XPath 使用路徑表達式來選取 XML 文檔中的節點或者節點集。這些路徑表達式和咱們在常規的電腦文件系統中看到的表達式很是類似。

選區節點

表達式 描述
節點的名字 選取此節點中的全部子節點
/ 從根節點選取
// 選取當前節點文檔中的任意一個節點
. 選取當前節點
.. 選取當前節點的父節點
@ 選取屬性
from selenium import webdriver

'''
<html><head>
  <base href="http://example.com/">
  <title>Example website</title>
 </head>
 <body>
  <div id="images">
   <a href="image1.html">Name: My image 1 <br><img src="image1_thumb.jpg"></a>
   <a href="image2.html">Name: My image 2 <br><img src="image2_thumb.jpg"></a>
   <a href="image3.html">Name: My image 3 <br><img src="image3_thumb.jpg"></a>
   <a href="image4.html">Name: My image 4 <br><img src="image4_thumb.jpg"></a>
   <a href="image5.html">Name: My image 5 <br><img src="image5_thumb.jpg"></a>
  </div>
</body></html>
'''

from selenium import webdriver
driver = webdriver.Chrome()
try:
    driver.get('https://doc.scrapy.org/en/latest/_static/selectors-sample1.html')
    driver.implicitly_wait(3)
    
    # 獲取當html標籤內的全部子節點
    html = driver.find_element_by_xpath('html')
    # 查找html中全部的a標籤
    a_s = html.find_elements_by_tag_name('a')
    print(len(a_s))
    
    # 從根節點開始查找html元素
    html = driver.find_element_by_xpath('./html')
    print(html.tag_name)
    
    # 查找html元素子節點內的body標籤,注意只能從根開始查找
    body = driver.find_element_by_xpath('html/body')
    print(body.tag_name)
    
    # 從當前文檔內全局查找,找全部的img標籤
    imgs = driver.find_elements_by_xpath('//img')
    for img in imgs:
        print(img.get_attribute('src'))
    
    #查找html元素下的全部a的節點
    a_tag_s = driver.find_elements_by_xpath('html//a')
    for a in a_tag_s:
        print(a.get_attribute('href'))
finally:
    driver.close()

3獲取標籤屬性(瞭解)

標籤屬性 描述
id 標籤id
tag_name 標籤名
size 標籤大小
location 標籤高寬
from selenium import webdriver
from selenium.webdriver.common.by import By     # 按照什麼方式查找,By.ID,By.CSS_SELECTOR
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait   # 等待頁面加載某些元素
from time import sleep

browser = webdriver.Chrome()

try:
    browser.get('https://www.baidu.com/s?wd=美女')

    wait = WebDriverWait(browser,10)
    img_tag = wait.until(EC.presence_of_element_located((By.CLASS_NAME,'op-img-address-link-imgs')))

    #獲取標籤屬性
    print(img_tag.get_attribute('src'))

# 獲取標籤ID,位置,名稱,大小(瞭解)
    print(img_tag.id)
    print(img_tag.location)
    print(img_tag.tag_name)
    print(img_tag.size)

    # 獲取頁面上圖片長寬 大小
    print(img_tag.size['height'], img_tag.size['width'])
    print(img_tag.location['x'], img_tag.location['y'])


finally:
    browser.close()

元素交互操做

點擊清除

from selenium import webdriver  #用來驅動瀏覽器
from selenium.webdriver.common.keys import Keys     #鍵盤按鍵操做
import time

#獲取驅動瀏覽器配置信息對象,可對其信息進行修改
option = webdriver.ChromeOptions()
# 經過add_argument爲配置添加參數
# 此參數用於跳過 "正受到自動測試軟件的控制"
option.add_argument('disable-infobars')

driver = webdriver.Chrome(chrome_options=option)

try:
    driver.get('https://www.jd.com')
    driver.implicitly_wait(10)

    input_tag = driver.find_element_by_id('key')
    input_tag.send_keys('大炮')
    search_button = driver.find_element_by_class_name('button').click()
    time.sleep(1)

    #清空
    input_tag = driver.find_element_by_class_name('text')
    input_tag.clear()
    input_tag.send_keys('哇哈哈哈')
    input_tag.send_keys(Keys.ENTER)

except Exception:

    driver.close()

Action Chains

from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By     #按照上面方式查找,By.ID,By.css_SELECTOR
from selenium.webdriver.common.keys import Keys     #鍵盤按鍵操做
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait       #等待頁面加載某些元素
import time

driver = webdriver.Chrome()
driver.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
wait = WebDriverWait(driver,3)
# driver.implicitly_wait(3)     使用隱式等待

try:
    driver.switch_to.frame('iframeResult')      ##切換到iframeResult
    sourse = driver.find_element_by_id('draggable')
    target = driver.find_element_by_id('droppable')
    
    # 方式一:基於同一個動做鏈串行執行
    # actions = ActionChains(driver)#拿到動做鏈對象
    # actions.drag_and_drop(sourse,target)#把動做放到動做鏈中,準備串執行
    # actions.perform()
    
    # 方式二:不一樣的動做鏈,每次移動的位移都不一樣
    ActionChains(driver).click_and_hold(sourse).perform()
    distance = target.location['x'] - sourse.location['x']
    
    track = 0
    while track < distance:
        ActionChains(driver).move_by_offset(xoffset=2,yoffset=0).perform()
        track += 2
    
    ActionChains(driver).release().perform()
finally:
    driver.close()

在交互動做比較難實現的時候能夠本身寫JS(萬能方法 )

from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By #按照什麼方式查找,By.ID,By.CSS_SELECTOR
from selenium.webdriver.common.keys import Keys #鍵盤按鍵操做
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait #等待頁面加載某些元素

try:
    browser = webdriver.Chrome()
    browser.get('https://www.baidu.com')
    browser.execute_script('alert("hello world")')   #打印警告
finally:
    browser.close()

frame的切換

frame至關於一個單獨的網頁,在父frame裏是沒法直接看到字frame的元素的,必須switch_to_frame切換到該frame下,才能進一步查找

from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By     #按照上面方式找,By.ID,BY.css_SELECTOR
from selenium.webdriver.common.keys import Keys     #鍵盤按鍵操做
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait       #等待頁面加載元素

try:
    browser = webdriver.Chrome()
    browser.get("http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable")
    browser.switch_to.frame('iframeResult') #切換到id爲iframeResult的farme
    tag1 = browser.find_element_by_id('droppable')
    print(tag1)

    # tag2=browser.find_element_by_id('textareaCode') #報錯,在子frame裏沒法查看到父frame的元素
    browser.switch_to.frame()   #切回父frame,就能夠查到了
    tag2 = browser.find_element_by_id('textareaCode')
    print(tag2)
except:
    browser.close()

模擬瀏覽器的前進後退

import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://www.baidu.com')
driver.get('https://www.taobao.com')
driver.get('https://www.sina.com.cn')

driver.back()
time.sleep(2)
driver.forward()
driver.close()

選項卡管理

#選項卡管理:切換選項卡,有js的方式windows.open,有windows快捷鍵:ctrl+t等,最通用的就是js的方式
from selenium import webdriver
import time

driver = webdriver.Chrome()
driver.get_cookie('https://baidu.com')
driver.execute_script('window.open()')

print(driver.window_handles)        #獲取全部的選項卡
driver.switch_to_window(driver.window_handles[1])
driver.get('https://www.taobao.com')
time.sleep(1)
driver.switch_to_window(driver.window_handles[0])
driver.get('https://www.sina.com.cn')

異常處理

from selenium import webdriver
from selenium.common.exceptions import TimeoutException,NoSuchElementException,NoSuchFrameException

try:
    driver = webdriver.Chrome()
    driver.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
    driver.switch_to_frame('iframssseResult')
except TimeoutException as e:
    print(e)
except NoSuchFrameException as e:
    print(e)
finally:
    driver.close()
相關文章
相關標籤/搜索