日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

爬虫学习笔记(十六)—— Selenium

發布時間:2025/3/21 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 爬虫学习笔记(十六)—— Selenium 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Selenium是一個主要用于Web應用程序自動化測試的工具集合,在行業內已經得到廣泛的應用。

文章目錄

  • 一、簡介
    • 1.1、作用
    • 1.2、運行環境
    • 1.3、注意事項
  • 二、基本使用
    • 2.1、原理
    • 2.2、安裝
      • 2.2.1、selenium安裝
      • 2.2.2、瀏覽器驅動安裝
    • 2.3、元素選取
      • 2.3.1、find_element(s)_by__...方法
      • 2.3.2、By對象查找
      • 2.3.3、文本輸入/提交
  • 三、動作切換
    • 3.1、窗口切換
    • 3.2、頁面(frame)切換
    • 3.2、頁面彈窗
  • 四、等待
    • 4.1、簡介
    • 4.2、顯式等待
    • 4.3、expected_conditions條件
    • 4.4、隱性等待
    • 4.5、強制等待
    • 4.6、代碼示例
  • 五、動作鏈
  • 六、補充知識點
    • 6.1、常用方法
    • 6.2、無界面設置

一、簡介

1.1、作用

  • 自動化測試
    通過它,我們可以寫出自動化程序,模擬瀏覽器里操作web界面。 比如點擊界面按鈕,在文本框中輸入文字等操作。
  • 獲取信息
    而且還能從web界面獲取信息。 比如招聘網站職位信息,財經網站股票價格信息 等等,然后用程序進行分析處理。

  • 1.2、運行環境

    Selenium測試直接運行在瀏覽器中,就好像一個真正的用戶在操作一樣, 支持大部分主流的瀏覽器,包括IE,Firefox,Safari,Chrome,Opera等。

    我們可以利用它來模擬用戶點擊訪問網站,繞過一些復雜的認證場景。

    通過selnium+驅動瀏覽器這種組合可以直接渲染解析js,繞過大部分的參數構造和反爬。


    1.3、注意事項

    新版本的Selenium已經不在支持phantomjs,原作者也已經放棄維護該項目了。

    還有在做爬蟲的時候盡量不要用這種方法,Selenium+瀏覽器的組合速度慢,應付不了數據量比較大的爬取以及并發爬取。并且很吃電腦資源。


    二、基本使用

    2.1、原理

    1. WebDriver API(基于Java、Python、C#等語言)

    對于Python語言來說,就是下載下來的selenium庫。

    2. 瀏覽器的驅動(browser driver)

    每個瀏覽器都有自己的驅動,均以exe文件形式存在

    https://chromedriver.storage.googleapis.com/index.html

    比如谷歌的chromedriver.exe、火狐的geckodriver.exe、IE的IEDriverServer.exe

    3. 瀏覽器

    瀏覽器當然就是我們很熟悉的常用的各種瀏覽器。

    那在WebDriver腳本運行的時候,它們之間是如何通信的呢?為什么同一個browser driver即可以處理java語言的腳本,也可以處理python語言的腳本呢?

    讓我們來看一下,一條Selenium腳本執行時后端都發生了哪些事情:

  • 對于每一條Selenium腳本,一個http請求會被創建并且發送給瀏覽器的驅動
  • 瀏覽器驅動中包含了一個HTTP Server,用來接收這些http請求
  • HTTP Server接收到請求后根據請求來具體操控對應的瀏覽器
  • 瀏覽器執行具體的測試步驟
  • 瀏覽器將步驟執行結果返回給HTTP Server
  • HTTP Server又將結果返回給Selenium的腳本,如果是錯誤的http代碼我們就會在控制臺看到對應的報錯信息。

  • 2.2、安裝

    2.2.1、selenium安裝

    終端輸入命令:

    pip install selenium

    2.2.2、瀏覽器驅動安裝

    chrome驅動下載地址:https://chromedriver.storage.googleapis.com/index.html

    注意:每個驅動該對應每個瀏覽器;有時候瀏覽器會自動升級,導致瀏覽器不可用;


    2.3、元素選取

    2.3.1、find_element(s)by_…方法

    在一個頁面中有很多不同的策略可以定位一個元素。我們可以選擇最合適的方法去查找元素。Selenium提供了下列的方法:

    單個元素查找方法作用
    find_element_by_xpath()通過Xpath查找
    find_element_by_class_name()通過class屬性查找
    find_element_by_id()通過id屬性查找
    find_element_by_name()通過name屬性進行查找
    find_element_by_css_selector()通過css選擇器查找 語法規則
    find_element_by_link_text()通過鏈接文本查找
    find_element_by_partial_link_text()通過鏈接文本的部分匹配查找
    find_element_by_tag_name()通過標簽名查找

    : 其中的element加上一個s,則是對應的多個元素的查找方法.

    示例:
    注意:webdriver.Chrome()的參數是你驅動的位置,當然如果有放到python文件的Scripts下或者有添加到環境變量中就可以不用寫

    from selenium import webdriverwb = webdriver.Chrome(r'D:\SoftWare\Python\Python36\Scripts\chromedriver.exe') wb.get('https://www.51zxw.net/List.aspx?cid=451') #點擊“首頁” #通過Xpath查找 home_page =wb.find_element_by_xpath('//div[@class="headLinks ml-10"]/a') # 通過css選擇器查找 # home_page =wb.find_element_by_css_selector('.headLinks a') home_page.click()

    結果展示:


    2.3.2、By對象查找

    By對象導入: from selenium.webdriver.common.by import By

    除了以上的多種查找方式,還有兩種私有方法集成了上面的所有的查找方法,讓我們更方便的使用:

    方法作用
    find_element(By.XPATH, ‘//button/span’)通過Xpath查找一個
    find_elements(By.XPATH, ‘//button/span’)通過Xpath查找多個

    其中的第一個參數可以選擇使用查找的方法,By.xxx使用xxx方式解析,解析方法如下:

    • ID:通過id屬性查找
    • XPATH :通過Xpath查找
    • LINK_TEXT:通過鏈接文本查找
    • PARTIAL_LINK_TEXT :通過鏈接文本的部分匹配查找
    • NAME:通過name屬性進行查找
    • TAG_NAME:通過標簽名查找
    • CLASS_NAME:通過class屬性查找
    • CSS_SELECTOR :通過css選擇器查找

    示例:

    from selenium import webdriver from selenium.webdriver.common.by import Bywb = webdriver.Chrome() #驅動已經添加到環境變量,所以可以不用寫參數 wb.get('https://www.51zxw.net/List.aspx?cid=451')#通過Xpath查找 home_page = wb.find_element(By.XPATH,'//div[@class="headLinks ml-10"]/a') home_page.click()

    結果展示:


    2.3.3、文本輸入/提交

    當我們需要通過selenium完成一個在網站中進行搜索的功能,前面我們已經知道了如何選取定位一個元素了,假如是定位到了一個輸入框的元素,那么我們就要進行查詢數據的輸入和提交了。

    方法作用
    send_keys()文本輸入
    click()文本提交

    示例:

    from selenium import webdriver from selenium.webdriver.common.by import Bywb = webdriver.Chrome() wb.get('https://www.51zxw.net/List.aspx?cid=451')#通過id屬性定位到搜索框 home_page = wb.find_element_by_id("keyWordsT") #搜索框輸入 Python home_page.send_keys('Python') #定位到搜索按鈕 submitbtn = wb.find_element_by_xpath('//button[@type="submit"]') #點擊搜索按鈕 submitbtn.click()

    結果展示:


    三、動作切換

    3.1、窗口切換

    在開始講解之前我們先來看一個示例:

    from selenium import webdriver from selenium.webdriver.common.by import Bywb = webdriver.Chrome() wb.get('https://www.51zxw.net/List.aspx?cid=451') print(wb.title)openjs = 'window.open("https://www.csdn.net/")' wb.execute_script(openjs) print(wb.title)

    結果:

    程序開發-我要自學網 程序開發-我要自學網

    通過結果我們可以看到,雖然瀏覽器給我們打開了第二個窗口并且停留在第二個窗口,但是其本質還是停留在第一個打開的窗口,因此我們需要進行窗口切換。

    用selenium操作瀏覽器如果需要在打開新的頁面,這個時候會有這個問題,因為我們用selenium操作的是第一個打開的窗口,所以新打開的頁面我們是無法去操作的,所以我們要用到切換窗口:即handle切換的方法

    方法作用
    widgetjs = ‘window.open(“https://www.baidu.com”);’
    chrome.execute_script(widgetjs )
    打開新標簽
    window_handles獲取所有頁面窗口的句柄
    current_window_handle獲取當前頁面窗口的句柄
    switch_to.window(window_name)定位頁面轉到指定的window_name頁面

    注意

    • window_handles 的順序并不是瀏覽器上標簽的順序,盡量避免多標簽操作

    示例:

    from selenium import webdriverwb = webdriver.Chrome() wb.get('https://www.51zxw.net/List.aspx?cid=451') print(wb.title) #當前打印窗口的標題openjs = 'window.open("https://www.csdn.net/")' wb.execute_script(openjs) print(wb.title) #當前打印窗口的標題print('所有頁面窗口的句柄: ',wb.window_handles) #打印所有頁面窗口的句柄 print('當前頁面窗口的句柄: ',wb.current_window_handle) #獲取當前頁面窗口的句柄wb.switch_to.window(wb.window_handles[1]) #通過上面打印比較 定位頁面轉到第二個窗口頁面 print(wb.title) #獲取當前頁面窗口的句柄

    結果:

    程序開發-我要自學網 程序開發-我要自學網 #我們還沒切換句柄,所以是還是第一個窗口 所有頁面窗口的句柄: ['CDwindow-4ACAD14BE66BD92795930B70D8CA1FA7', 'CDwindow-C1D8821CFEBFE3A0C0AF456231EF2CB3'] 當前頁面窗口的句柄: CDwindow-4ACAD14BE66BD92795930B70D8CA1FA7 CSDN - 專業開發者社區

    由于很難知道其他頁面對應的handle是什么,如果只有少數的標簽也許還能應付,但是當打開了相當多標簽時就很難對他們進行處理了,所以要盡量避免多標簽的操作。


    3.2、頁面(frame)切換

    在實際的爬蟲中,明明定位的路徑沒問題,這個時候我們可以考慮一下是否是該頁面存在frame的問題導有時候我們會遇到找不到元素的問題致的定位不到元素。

    知識點補充:什么是frame呢?
    frame是一個框架標簽,通過使用框架可以在一個瀏覽器窗口中顯示不止一個頁面,也就是說,在一個窗口中展示多個頁面,每個頁面稱之為一個框架,并且每個框架獨立于其他的框架。這個frame標簽一共有三種,分別是frameset、frame、iframe,frameset跟其他普通標簽沒有區別,不會影響到正常的定位,而frame與iframe對selenium定位而言是一樣的,selenium有一組方法對frame進行操作。reference是傳入的參數,用來定位frame,可以傳入id、name、index以及selenium的WebElement對象

    方法作用
    switch_to.frame(frame_reference)切到指定frame,可用id或name(str)、index(int)、元素(WebElement)定位
    switch_to.parent_frame()切到父級frame,如果已是主文檔,則無效果, 相當于后退回去
    switch_to.default_content()切換到主頁面,DOM樹最開始的frame

    簡單示例:

    import time from selenium import webdriverwb = webdriver.Chrome() wb.get('https://study.163.com/')# 關閉頁面彈出的小窗口 ok_btn = wb.find_element_by_xpath('//span[@class="ux-btn th-bk-main ux-btn- ux-btn- ux-modal-btn um-modal-btn_ok th-bk-main"]') ok_btn.click() # 登錄窗口 login_btn = wb.find_element_by_xpath('//div[@class="go-login f-ib th-fs0fc6"]') login_btn.click()time.sleep(2) #先等2秒,代碼執行過快,登錄輸入框加載需要時間,否則會出錯 # 切換frame fr = wb.find_element_by_xpath('//iframe[@frameborder="0"]') wb.switch_to.frame(fr)# 賬號輸入框輸入 name_input = wb.find_element_by_id('phoneipt') name_input.send_keys('123456789') # 密碼輸入 pwd_input = wb.find_element_by_xpath('//input[@class="j-inputtext dlemail"]') pwd_input.send_keys('10987654321')

    結果展示:


    3.2、頁面彈窗

    有的時候還會遇到彈窗的問題, 主要有兩種一種是瀏覽器彈窗(alert/prompt),另一種是自定義彈窗。自定義彈窗,就是一個自定義的div層,是隱藏頁面中的,當觸發了這個彈窗后,他就顯示出來,這種方式我們通過正常的定位方式是可以定位到的。

    alert彈窗,就要用下面的方法處理:

    方法作用
    switch_to.alert定位到alert彈窗,返回一個彈窗的對象
    dismiss()對彈窗對象的取消操作(相當于點擊彈窗上的取消按鈕)
    accept()對彈窗對象的確定操作(相當于點擊彈窗上的確定按鈕)
    send_keys(key)對彈窗對象內的輸入框輸入數據(針對于prompt彈窗)
    text獲取彈窗內的文本

    示例
    測試html代碼:

    <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>selenium</title> </head> <body><input id="alert" value="alert" type="button" onclick="alert('this is alert!!!')"><input id="confirm" value="confirm" type="button" onclick="confirm('this is confirm!!!')"><input id="prompt" value="prompt" type="button" onclick="var name = prompt('請輸入用戶名:','請輸入');document.write(name)"> </body> </html>

    效果:

    python代碼:

    import time from selenium import webdriverwb = webdriver.Chrome() wb.get(r'D:\html test\一些示例\ex.html') # alert 彈窗 wb.find_element_by_id("alert").click() alert_tag = wb.switch_to.alert print(alert_tag.text) time.sleep(2) #稍微延遲下,看得比較直觀 alert_tag.accept()# prompt 彈窗 # # wb.find_element_by_id("prompt").click() # prompt_tag = wb.switch_to.alert # print(prompt_tag.text) # prompt_tag.send_keys('hello world!!!') # time.sleep(2) #稍微延遲下,看得比較直觀 # prompt_tag.accept()# confirm 彈窗 # # wb.find_element_by_id("confirm").click() # confirm_tag = wb.switch_to.alert # print(confirm_tag.text) # time.sleep(2) #稍微延遲下,看得比較直觀 # confirm_tag.accept()

    結果展示(這里我就只演示一個):

    打印結果:

    this is alert!!!

    四、等待

    4.1、簡介

    在selenium操作瀏覽器的過程中,每一次請求url,selenium都會等待頁面加載完成以后,才會將操作權限在交給我們的程序。

    ?但是,由于ajax和各種JS代碼的異步加載問題,當一個頁面被加載到瀏覽器時,該頁面內的元素可以在不同的時間點被加載,這就使得元素的定位變得十分困難,當元素不再頁面中時,使用selenium去查找的時候會拋出ElementNotVisibleException異常。

    ? 為了解決這個問題,selenium提供了兩種等待頁面加載的方式,顯示等待和隱式等待,讓我們可以等待元素加載完成后在進行操作。


    4.2、顯式等待

    顯式等待: 顯式等待指定某個條件,然后設置最長等待時間,程序每隔XX時間看一眼,如果條件成立,則執行下一步,否則繼續等待,直到超過設置的最長時間,然后拋出超時異常(TimeoutException)。

    顯示等待主要使用了WebDriverWait類與expected_conditions模塊。

    一般寫法:

    WebDriverWait(driver, timeout, poll_frequency, igonred_exceptions).until(method, message)

    參數:

    • Driver:傳入WebDriver實例。
    • timeout: 超時時間,等待的最長時間(同時要考慮隱性等待時間)
    • poll_frequency: 調用until中的方法的間隔時間,默認是0.5秒
    • ignored_exceptions: 忽略的異常,如果在調用until的過程中拋出這個元組中的異常,則不中斷代碼,繼續等待。
    • Method:可執行方法
    • Message:超時時返回的信息

    4.3、expected_conditions條件

    expected_conditions是selenium的一個子模塊,其中包含一系列可用于判斷的條件,配合該類的方法,就能夠根據條件而進行靈活地等待了。

    ActionChains提供的方法作用
    title_is
    title_contains
    這兩個條件類驗證title,驗證傳入的參數title是否等于或包含于driver
    presence_of_element_located presence_of_all_elements_located這兩個條件驗證元素是否出現,傳入的參數都是元組類型的locator,如(By.ID, ‘kw’)顧名思義,一個只要一個符合條件的元素加載出來就通過;另一個必須所有符合條件的元素都加載出來才行
    visibility_of_element_located invisibility_of_element_located visibility_of這三個條件驗證元素是否可見,前兩個傳入參數是元組類型的locator,第三個傳入WebElement
    text_to_be_present_in_element text_to_be_present_in_element_value判斷某段文本是否出現在某元素中,一個判斷元素的text,一個判斷元素的value
    frame_to_be_available_and_switch_to_it判斷frame是否可切入,可傳入locator元組或者直接傳入定位方式:id、name、index或WebElement
    alert_is_present判斷是否有alert出現
    element_to_be_clickable判斷元素是否可點擊,傳入locator

    4.4、隱性等待

    隱性等待implicitly_wait(xx) :設置了一個最長等待時間,如果在規定時間內網頁加載完成,則執行下一步,否則一直等到時間截止,然后執行下一步。

    弊端就是程序會一直等待整個頁面加載完成,就算你需要的元素加載出來了還是需要等待。,也就是一般情況下你看到瀏覽器標簽欄那個小圈不再轉,才會執行下一步。

    隱性等待對整個driver的周期都起作用,所以只要設置一次即可;
    隱性等待和顯性等待可以同時用,但要注意:等待的最長時間取兩者之中的大者;

    默認等待時間為0,可以通過下面的方式設置:

    from selenium import webdriver driver = webdriver.Chrome() ······ driver.implicitly_wait(10) #隱式等待,最長10s ······

    示例


    4.5、強制等待

    強制等待就是不論如何,在此處都需要阻塞等待一段時間,使用方式如下:

    import time time.sleep(3) #等待3秒

    4.6、代碼示例

    from selenium import webdriver import time from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.common.by import Bywb = webdriver.Chrome() wb.get('https://study.163.com/')# 關閉頁面彈出的小窗口 ok_btn = wb.find_element_by_xpath('//span[@class="ux-btn th-bk-main ux-btn- ux-btn- ux-modal-btn um-modal-btn_ok th-bk-main"]') ok_btn.click() # 登錄窗口 login_btn = wb.find_element_by_xpath('//div[@class="go-login f-ib th-fs0fc6"]') login_btn.click()#設置顯示等待 locater = (By.XPATH,'//iframe[@frameborder="0"]') WebDriverWait(driver=wb,timeout=3,poll_frequency=0.4).until(EC.presence_of_element_located(locater),message='找不到元素!') #隱式等待 最長3s # wb.implicitly_wait(3) # 強制等待 3s # time.sleep(3) # 切換frame 加載需要時間,所以要設等待 fr = wb.find_element_by_xpath('//iframe[@frameborder="0"]') wb.switch_to.frame(fr) # 賬號輸入框輸入 name_input = wb.find_element_by_id('phoneipt') name_input.send_keys('123456789') # 密碼輸入 pwd_input = wb.find_element_by_xpath('//input[@class="j-inputtext dlemail"]') pwd_input.send_keys('10987654321')

    五、動作鏈

    在selenium當中除了簡單的點擊動作外,還有一些稍微復雜的動作,就需要用到ActionChains(動作鏈)這個子模塊來滿足我們的需求。

    ActionChains可以完成復雜一點的頁面交互行為,例如元素的拖拽,鼠標移動,懸停行為,內容菜單交互。

    它的執行原理就是當調用ActionChains方法的時候不會立即執行,而是將所有的操作暫時儲存在一個隊列中,當調用perform()方法的時候,會按照隊列中放入的先后順序執行前面的操作。

    ActionChains包:from selenium.webdriver.common.action_chains import ActionChains

    ActionChains提供的方法作用
    click(on_element=None)鼠標左鍵單擊
    double_click(on_element=None)雙擊鼠標左鍵
    context_click(on_element=None)點擊鼠標右鍵
    click_and_hold(on_element=None)點擊鼠標左鍵,按住不放
    release(on_element=None)在某個元素位置松開鼠標左鍵
    drag_and_drop(source, target)拖拽到某個元素然后松開
    drag_and_drop_by_offset(source, xoffset, yoffset)拖拽到某個坐標然后松開
    move_to_element(to_element)鼠標移動到某個元素
    move_by_offset(xoffset, yoffset)移動鼠標到指定的x,y位置
    move_to_element_with_offset(to_element, xoffset, yoffset)將鼠標移動到距某個元素多少距離的位置
    perform()執行鏈中的所有動作

    示例

    import time from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChainsdriver = webdriver.Chrome()driver.get('http://www.treejs.cn/v3/demo/cn/exedit/drag.html') time.sleep(2) element1 = driver.find_element_by_id('treeDemo_2_span') target = driver.find_element_by_id('treeDemo_3_span') ActionChains(driver).drag_and_drop(element1, target).perform()element2 = driver.find_element_by_id('treeDemo_12_span') ActionChains(driver).drag_and_drop(element2,target).perform()

    結果展示:


    六、補充知識點

    6.1、常用方法

    方法說明
    Chrome.refresh()刷新頁面
    Chrome.close()關閉當前標簽
    Chrome.quit()關閉所有標簽
    Chrome.page_source網頁源代碼
    Chrome.cookies本頁保存的cookie
    Chrome.maximize_window()最大化窗口

    6.2、無界面設置

    from selenium.webdriver.chrome.options import Options from selenium import webdriverchrome_options=Options() chrome_options.add_argument("--headless") drive = webdriver.Chrome(options=chrome_options)drive.get('https://www.51zxw.net/List.aspx?cid=451') print(drive.page_source) #獲取網頁源碼

    總結

    以上是生活随笔為你收集整理的爬虫学习笔记(十六)—— Selenium的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。