Python爬蟲利器:Selenium的用法

來源:互聯網
上載者:User

標籤:

本文和大家分享的主要是python 爬蟲 利器Selenium的相關內容,一起來看看吧,希望對大家 學習python爬蟲有所協助。Selenium  是什嗎?一句話,自動化測試載入器。它支援各種瀏覽器,包括  Chrome , Safari , Firefox 等主流介面式瀏覽器,如果你在這些瀏覽器裡面安裝一個  Selenium  的外掛程式,那麼便可以方便地實現 Web介面的測試。換句話說叫  Selenium  支援這些瀏覽器驅動。話說回來, PhantomJS 不也是一個瀏覽器嗎,那麼  Selenium  支援不?答案是肯定的,這樣二者便可以實現無縫對接了。然後又有什麼好訊息呢?Selenium 支援多種語言開發,比如  Java , C , Ruby 等等,有  Python  嗎?那是必須的!哦這可真是天大的好訊息啊。嗯,所以呢?安裝一下 Python  的  Selenium  庫,再安裝好  PhantomJS ,不就可以實現  Python +Selenium + PhantomJS  的無縫對接了嘛! PhantomJS  用來渲染解析 JS , Selenium  用來驅動以及與 Python  的對接, Python  進行後期的處理,完美的三劍客!有人問,為什麼不直接用瀏覽器而用一個沒介面的 PhantomJS  呢?答案是:效率高!Selenium  有兩個版本,目前最新版本是  2.53.1 ( 2016/3/22 ) SeleniumSelenium 2 ,又名  WebDriver ,它的主要新功能是整合了  Selenium 1.0  以及  WebDriver (WebDriver  曾經是  Selenium  的競爭者)。也就是說  Selenium 2  是  Selenium  和  WebDriver  兩個項目的合并,即  Selenium 2  相容  Selenium ,它既支援  Selenium API  也支援  WebDriver API 。 查看詳情說明 Webdriver嗯,通過以上描述,我們應該對 Selenium  有了大概對認識,接下來就讓我們開始進入動態爬取的新世界吧。本文參考內容來自 Selenium 官網  SeleniumPython 文檔安裝首先安裝 Selenium pip install selenium快速開始 初步體驗我們先來一個小例子感受一下 Selenium ,這裡我們用  Chrome  瀏覽器來測試,方便查看效果,到真正爬取的時候換回 PhantomJS  即可。from selenium  import webdriverbrowser = webdriver.Chrome()browser. get(’http://www.baidu.com/’)運行這段代碼,會自動開啟瀏覽器,然後訪問百度。如果程式執行錯誤,瀏覽器沒有開啟,那麼應該是沒有裝 Chrome  瀏覽器或者  Chrome  驅動沒有配置在環境變數裡。下載驅動,然後將驅動檔案路徑配置在環境變數即可。瀏覽器驅動下載:  https://sites.google.com/a/chromium.org/chromedriver/downloads比如我的是 Mac OS ,就把下載好的檔案放在  /usr/bin  目錄下就可以了。 類比提交下面的代碼實現了類比提交提交搜尋的功能,首先等頁面載入完成,然後輸入到搜尋方塊文本,點擊提交。from selenium  import webdriverfrom selenium.webdriver.common.keys  import Keysdriver = webdriver.Chrome()driver. get("http://www.python.org")assert "Python"  in driver.titleelem = driver.find_element_by_name("q")elem.send_keys("pycon")elem.send_keys(Keys.RETURN)print driver.page_source同樣是在 Chrome  裡面測試,感受一下。 執行個體說明其中 driver.get  方法會開啟請求的 URL , WebDriver  會等待頁面完全載入完成之後才會返回,即程式會等待頁面的所有內容載入完成, JS 渲染完畢之後才繼續往下執行。注意:如果這裡用到了特別多的  Ajax 的話,程式可能不知道是否已經完全載入完畢。WebDriver  提供了許多尋找網頁元素的方法,譬如  find_element_by_*  的方法。例如一個輸入框可以通過 find_element_by_name  方法尋找  name  屬性來確定。然後我們輸入來文本然後類比點擊了斷行符號,就像我們敲擊鍵盤一樣。我們可以利用  Keys  這個類來類比鍵盤輸入。最後最重要的一點,擷取網頁渲染後的原始碼,輸出 page_source  屬性即可。這樣,我們就可以做到網頁的動態爬取了。 測試案例有了以上特性,我們當然可以用來寫測試範例了。 import unittest from selenium  import webdriver from selenium.webdriver.common.keys  import Keys class  PythonOrgSearch(unittest.TestCase): def  setUp(self):self.driver = webdriver.Chrome() def  test_search_in_python_org(self):driver = self.driverdriver.get("http://www.python.org")self.assertIn("Python", driver.title)elem = driver.find_element_by_name("q")elem.send_keys("pycon")elem.send_keys(Keys.RETURN) assert "No results found."  not  in driver.page_source def  tearDown(self):self.driver.close() if __name__ == "__main__":unittest.main()運行程式,同樣的功能,我們將其封裝為測試標準類的形式。 測試案例測試案例是繼承了 unittest.TestCase  類,繼承這個類表明這是一個測試類別。 setUp 方法是初始化的方法,這個方法會在每個測試類別中自動調用。每一個測試方法命名都有規範,必須以  test  開頭,會自動執行。最後的  tearDown  方法會在每一個測試方法結束之後調用。這相當於最後的析構方法。在這個方法裡寫的是  close  方法,你還可以寫  quit  方法。不過  close  方法相當於關閉了這個 TAB  選項卡,然而  quit  是退出了整個瀏覽器。當你只開啟了一個  TAB  選項卡的時候,關閉的時候也會將整個瀏覽器關閉。頁面操作 頁面互動僅僅抓取頁面沒有多大卵用,我們真正要做的是做到和頁面互動,比如點擊,輸入等等。那麼前提就是要找到頁面中的元素。WebDriver 提供了各種方法來尋找元素。例如下面有一個表單輸入框。<input  type="text" name="passwd" id="passwd-id" />我們可以這樣擷取它element = driver.find_element_by_id("passwd-id")element = driver.find_element_by_name("passwd")element = driver.find_elements_by_tag_name("input")element = driver.find_element_by_xpath("//input[@id=’passwd-id’]")你還可以通過它的文本連結來擷取,但是要小心,文本必須完全符合才可以,所以這並不是一個很好的匹配方式。而且你在用 xpath  的時候還需要注意的是,如果有多個元素匹配了  xpath ,它只會返回第一個匹配的元素。如果沒有找到,那麼會拋出  NoSuchElementException  的異常。擷取了元素之後,下一步當然就是向文本輸入內容了,可以利用下面的方法 element.send_keys("some text")同樣你還可以利用 Keys  這個類來類比點擊某個按鍵。 element.send_keys("and some", Keys.ARROW_DOWN)你可以對任何擷取到到元素使用 send_keys  方法,就像你在  GMail  裡面點擊發送鍵一樣。不過這樣會導致的結果就是輸入的文本不會自動清除。所以輸入的文本都會在原來的基礎上繼續輸入。你可以用下面的方法來清除輸入文本的內容。 element.clear()這樣輸入的文本會被清除。 填充表單我們已經知道了怎樣向文字框中輸入文字,但是其它的表單元素呢?例如下拉選項卡的的處理可以如下element = driver.find_element_by_xpath("//select[@name=’name’]")all_options = element.find_elements_by_tag_name("option") for  option  in all_options:print("Value is: %s" %  option.get_attribute("value")) option.click()首先擷取了第一個 select  元素,也就是下拉選項卡。然後輪流設定了  select  選項卡中的每一個  option 選項。你可以看到,這並不是一個非常有效方法。其實 WebDriver  中提供了一個叫  Select  的方法,可以協助我們完成這些事情。 from selenium.webdriver.support.ui import  Selectselect =Select(driver.find_element_by_name(’name’)) select.select_by_index(index)select.select_by_visible_text("text") select.select_by_value(value)如你所見,它可以根據索引來選擇,可以根據值來選擇,可以根據文字來選擇。是十分方便的。全部取消選擇怎麼辦呢?很簡單 select =  Select(driver.find_element_by_id(’id’)) select.deselect_all()這樣便可以取消所有的選擇。另外我們還可以通過下面的方法擷取所有的已選選項。select = Select(driver.find_element_by_xpath("xpath"))all_selected_options = select.all_selected_options擷取所有可選選項是 options = select.options如果你把表單都填好了,最後肯定要提交表單對吧。怎嗎提交呢?很簡單 driver.find_element_by_id("submit").click()這樣就相當於類比點擊了 submit  按鈕,做到表單提交。當然你也可以單獨提交某個元素 element.submit()方法,WebDriver  會在表單中尋找它所在的表單,如果發現這個元素並沒有被表單所包圍,那麼程式會拋出 NoSuchElementException  的異常。 元素拖拽要完成元素的拖拽,首先你需要指定被拖動的元素和拖動目標元素,然後利用 ActionChains  類來實現。element = driver.find_element_by_name("source")target = driver.find_element_by_name("target")from selenium.webdriver  import ActionChainsaction_chains = ActionChains(driver)action_chains.drag_and_drop(element, target).perform()這樣就實現了元素從 source  拖動到  target  的操作。 頁面切換一個瀏覽器肯定會有很多視窗,所以我們肯定要有方法來實現視窗的切換。切換視窗的方法如下 driver.switch_to_window("windowName")另外你可以使用 window_handles  方法來擷取每個視窗的操作對象。例如 for handle  in driver.window_handles:driver.switch_to_window(handle)另外切換 frame  的方法如下 driver.switch_to_frame(" frameName.0.child")這樣焦點會切換到一個 name  為  child  的  frame  上。 彈窗處理當你出發了某個事件之後,頁面出現了彈窗提示,那麼你怎樣來處理這個提示或者擷取提示資訊呢?alert = driver.switch_to_alert()通過上述方法可以擷取彈窗對象。 記錄那麼怎樣來操作頁面的前進和後退功能呢? driver.forward() driver.back()嗯,簡潔明了。 Cookies處理為頁面添加 Cookies ,用法如下# Go to the correct domaindriver.get("http://www.example.com")# Now set the cookie. This one’s valid for the entire domaincookie = {‘name’ : ‘foo’, ‘value’ : ‘bar’}driver.add_cookie(cookie)擷取頁面 Cookies ,用法如下# Go to the correct domaindriver.get("http://www.example.com")# And now output all the available cookies for the current URLdriver.get_cookies()以上便是 Cookies  的處理,同樣是非常簡單的。 元素選取關於元素的選取,有如下的API單個元素選取 find_element_by_idfind_element_by_namefind_element_by_xpathfind_element_by_link_textfind_element_by_partial_link_textfind_element_by_tag_namefind_element_by_class_namefind_element_by_css_selector多個元素選取 find_elements_by_namefind_elements_by_xpathfind_elements_by_link_textfind_elements_by_partial_link_textfind_elements_by_tag_namefind_elements_by_class_namefind_elements_by_css_selector另外還可以利用 By  類來確定哪種選擇方式 from selenium.webdriver.common. by import  Bydriver.find_element( By.XPATH, ’//button[text()="Some text"]’)driver.find_elements( By.XPATH, ’//button’)By  類的一些屬性如下 ID = "id"XPATH = "xpath"LINK_TEXT = "link text"PARTIAL_LINK_TEXT = "partial link text"NAME = "name"TAG_NAME = "tag name"CLASS_NAME = "class name"CSS_SELECTOR = "css selector"更詳細的元素選擇方法參見官方文件項目選擇:  http://selenium-python.readthedocs.org/en/latest/locating-elements.html頁面等待這是非常重要的一部分,現在的網頁越來越多採用了 Ajax  技術,這樣程式便不能確定何時某個元素完全載入出來了。這會讓元素定位困難而且會提高產生  ElementNotVisibleException  的機率。所以 Selenium  提供了兩種等待方式,一種是隱式等待,一種是顯式等待。隱式等待是等待特定的時間,顯式等待是指定某一條件直到這個條件成立時繼續執行。 顯式等待顯式等待指定某個條件,然後設定最長等待時間。如果在這個時間還沒有找到元素,那麼便會拋出異常了。 from selenium import webdriver from selenium.webdriver.common. by import Byfrom selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions  as ECdriver = webdriver.Chrome()driver. get("http://somedomain/url_that_delays_loading") try:element = WebDriverWait(driver, 10). until(EC.presence_of_element_located(( By.ID, "myDynamicElement"))) finally:driver.quit()程式預設會 500ms  調用一次來查看元素是否已經產生,如果本來元素就是存在的,那麼會立即返回。下面是一些內建的等待條件,你可以直接調用這些條件,而不用自己寫某些等待條件了。 等待條件title_istitle_containspresence_of_element_locatedvisibility_of_element_locatedvisibility_ofpresence_of_all_elements_locatedtext_to_be_present_in_elementtext_to_be_present_in_element_valueframe_to_be_available_and_switch_to_itinvisibility_of_element_locatedelement_to_be_clickable – it is Displayed and Enabled.staleness_ofelement_to_be_selectedelement_located_to_be_selectedelement_selection_state_to_beelement_located_selection_state_to_bealert_is_present from selenium.webdriver.sup port import expected_conditions as ECwait = WebDriverWait(driver, 10)element = wait.until(EC.element_to_be_clickable((By.ID,’someid’)))from selenium.webdriver.support import expected_conditions as ECwait = WebDriverWait(driver, 10)element = wait.until(EC.element_to_be_clickable((By.ID,’someid’))) 隱式等待隱式等待比較簡單,就是簡單地設定一個等待時間,單位為秒。 from selenium  import webdriverdriver = webdriver.Chrome()driver.implicitly_wait(10) # secondsdriver.get("http://somedomain/url_that_delays_loading")myDynamicElement = driver.find_element_by_id("myDynamicElement")當然如果不設定,預設等待時間為0 。程式架構對於頁面測試和分析,官方提供了一個比較明晰的代碼結構,可以參考。結語以上就是 Selenium  的基本用法,我們講解了頁面互動,頁面渲染之後的原始碼的擷取。這樣,即使頁面是  JS  渲染而成的,我們也可以手到擒來了。就是這麼溜!來源:網路

Python爬蟲利器:Selenium的用法

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.