Selenium本是一個用于Web應(yīng)用程序測試的工具。Selenium測試直接運行在瀏覽器中,就像真正的用戶在操作一樣。PhantomJS是一個基于WebKit的服務(wù)器端 JavaScript API。它全面支持web而不需瀏覽器支持。使用selenium和PhantomJS這兩個工具來爬蟲,可以實現(xiàn)很多功能。
Selenium和PhantomJS
selenium是一個強大的網(wǎng)絡(luò)數(shù)據(jù)采集工具,最初是為了網(wǎng)站自動化測試而開發(fā)的。它可以讓瀏覽器自動加載頁面,獲取需要的數(shù)據(jù),也可以截屏,或判斷網(wǎng)站上某些動作是否發(fā)生。
PhantomJS是一個無頭瀏覽器,它不會向用戶展示網(wǎng)頁的圖形界面。
簡單理解selenium就是完成模擬用戶所有操作的工具,而PhantomJS則是一個沒有圖形界面,可供selenium實現(xiàn)各種操作的瀏覽器。
代碼部分
#!/usr/bin/env python
# @Time : 2017/2/25
# @Author : AlPha
# @File : selenium模擬登陸教務(wù)網(wǎng)站.py
# @Version : 3.5
# @Software: PyCharm Community Edition
# @Blog : http://alpha87.github.io
from selenium import webdriver
browser = webdriver.PhantomJS(executable_path="C:\phantomjs.exe")
browser.implicitly_wait(30)
browser.get("http://210.31.122.109")
browser.find_element_by_name("txtUserName").clear()
browser.find_element_by_name("txtUserName").send_keys("201303010121")
browser.find_element_by_name("TextBox2").clear()
browser.find_element_by_name("TextBox2").send_keys("password")
browser.save_screenshot(str("登錄界面.jpg"))
browser.find_element_by_name("txtSecretCode").send_keys(input("輸入驗證碼\n>>> "))
browser.find_element_by_class_name("btn_dl").click()
print(browser.page_source)
browser.close()
分析代碼
from selenium import webdriver
用來導(dǎo)入selenium庫。
browser = webdriver.PhantomJS(executable_path="C:\phantomjs.exe")
用來指明PhantomJS可執(zhí)行文件的路徑。
browser.implicitly_wait(30)
是隱式等待30秒。一旦設(shè)定,browser對象實例的整個生命周期的隱式調(diào)用也就設(shè)定好了。
browser.get("http://210.31.122.189")
打開指定網(wǎng)址。
browser.find_element_by_name("txtUserName").clear()
browser.find_element_by_name("txtUserName").send_keys("201303010121")
browser.find_element_by_name("TextBox2").clear()
browser.find_element_by_name("TextBox2").send_keys("password")
這四行代碼分別對應(yīng)的是:
1.清除用戶名中原來的信息。
2.鍵入學(xué)號。
3.清除密碼中原來的信息。
4.鍵入密碼。
browser.save_screenshot(str("登錄界面.jpg"))
browser.find_element_by_name("txtSecretCode").send_keys(input("輸入驗證碼\n>>> "))
browser.find_element_by_class_name("btn_dl").click()
print(browser.page_source)
這四行代碼分別實現(xiàn)的功能是:
1.把登錄頁面截圖,保存到當(dāng)前文件夾下。(保存登錄頁面的截圖是為了可以查看當(dāng)前網(wǎng)頁的驗證碼)
2.鍵入驗證碼。
3.點擊登錄。
4.打印登錄以后頁面的源碼。
browser.close()
用來關(guān)閉操作。

selenium用法拓展
元素定位
Selenium提供了下面的方法進行元素定位:
find_element_by_id
find_element_by_name
find_element_by_xpath
find_element_by_link_text
find_element_by_partial_link_text
find_element_by_tag_name
find_element_by_class_name
find_element_by_css_selector
尋找多個元素(下列方法會返回一個列表):
find_elements_by_id
find_elements_by_name
find_elements_by_xpath
find_elements_by_link_text
find_elements_by_partial_link_text
find_elements_by_tag_name
find_elements_by_class_name
find_elements_by_css_selector
例如:
<html>
<body>
<form id="loginForm">
<input name="username" type="text" />
<input name="password" type="password" />
<input name="continue" type="submit" value="Login" />
</form>
</body>
<html>
可以這樣定位表單元素form:
login_form = driver.find_element_by_id('loginForm')
異步加載
現(xiàn)在很多Web應(yīng)用都在使用AJAX技術(shù)。瀏覽器載入一個頁面時,頁面內(nèi)的元素可能是在不同的時間載入的, 這會加大定位元素的困難程度,因為元素不在DOM里,會拋出 ElementNotVisibleException 異常, 使用 waits,我們就可以解決這個問題。
顯式等待
顯式的 waits 等待一個確定的條件觸發(fā)然后才進行更深一步的執(zhí)行。 最糟糕的的做法是 time.sleep(),這指定的條件是等待一個指定的時間段。 這里提供一些便利的方法讓你編寫的代碼只等待需要的時間,WebDriverWait 結(jié)合ExpectedCondition 是一種實現(xiàn)的方法:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Firefox()
driver.get("http://somedomain/url_that_delay_loading")
try:
element = WebDriverWait(driver,10).until(
EC.presence_of_element_located((By.ID,"myDynamicElement"))
)
finally:
driver.quit()
這段代碼會等待10秒,如果10秒內(nèi)找到元素則立即返回,否則會拋出 TimeoutException 異常, WebDriverWait默認(rèn)每500毫秒調(diào)用一下 ExpectedCondition直到它返回成功為止。ExpectedCondition 類型是布爾的,成功的返回值就是true,其他類型的 ExpectedCondition 成功的返回值就是 not null。
Expected Conditions
自動化網(wǎng)頁操作時,有許多頻繁使用到的通用條件。下面列出的是每一個條件的實現(xiàn)。 Selenium + Python 提供了許多方便的方法,因此你不需要自己編寫 expected_condition 的類, 或者創(chuàng)建你自己的通用包。
title_is
title_contains
presence_of_element_located
visibility_of_element_located
visibility_of
presence_of_all_elements_located
text_to_be_present_in_element
text_to_be_present_in_element_value
frame_to_be_available_and_switch_to_it
invisibility_of_element_located
element_to_be_clickable it
is Displayed and Enabled.
staleness_of
element_to_be_selected
element_located_to_be_selected
element_selection_state_to_be
element_located_selection_state_to_be
alert_is_present
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver,10)
element = wait.until(EC.element_to_be_clickable((By.ID,'someid')))
expected_conditions 模塊包含了一系列預(yù)定義的條件來和WebDriverWait使用。
隱式等待
當(dāng)我們要找一個或者一些不能立即可用的元素的時候,隱式 waits 會告訴WebDriver輪詢DOM指定的次數(shù),默認(rèn)設(shè)置是0次。 一旦設(shè)定,WebDriver對象實例的整個生命周期的隱式調(diào)用也就設(shè)定好了。
from selenium import webdriver
driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get("http://somedomain/url_that_delays_loading")
myDynamicElement = driver.find_element_by_id('myDynamicElement')
其他用法
這部分是我看其他教程總結(jié)的一些零碎用法。
1.瀏覽器最大化:
browser.maximize_window()
2.查看頁面:
browser.page_sources
3.設(shè)置瀏覽器寬和高:
browser.set_window_size(480,800)
4.操作對象常用方法:
click() #點擊對象
send_keys() #在對象上模擬輸入
text #獲取元素的文本信息
submit #用于提交表單,某些情況下和click()用法相同
5.截圖:
browser.save_screenshot
6.用鏈接文本定位超鏈接:
#源碼部分
<a href="continue.html">Continue</a>
#定位
continue_link = browser.find_element_by_link_text('Continue')
7.使用cookies:
cookies = {
"name":"foo"
"value":"bar"
}
browser.add_cookie(cookies)
# And now output all the available cookies for the current URL
driver.get_cookies()
8.前進和后退頁面:
browser.forward() #前進
browser.back() #后退