What
selenium 是一套完整的web應用程序測試系統,包含了測試的錄製(selenium IDE),編寫及運行(Selenium Remote Control)和測試的並行處理(Selenium Grid)。
就是相當於按鍵精靈,可以幫助你完成瀏覽器的操作,模擬瀏覽器。
Why
因爲有些頁面需要 ajax 後才顯示出真正的內容。
HOW
前期準備:
- install selenium 模塊,python 導入就行。
- 下載 geckodriver 驅動:下載地址
- 驅動解壓後取其路徑: …/geckodriver.exe
編碼:
from selenium import webdriver
browser = webdriver.Firefox(executable_path="D:/Python36/geckodriver.exe")
browser.get(url="http://www.baidu.com")
print(browser.page_source)
browser.close()
運行後會模擬打開瀏覽器,進入百度界面,最後關閉。
這也是 selenium 的特點,要搭配第三方瀏覽器纔行,而且會出現瀏覽器界面,但是對我們程序員來說,這沒有必要,所以有了 PhantomJS 這是一個無界面的瀏覽器,它會把網站加載到內存並執行頁面上的JavaScript,因爲不會展示圖形界面,所以運行起來比完整的瀏覽器更高效。PhantomJS 下載地址。
browser = webdriver.PhantomJS( executable_path="D:\\Python36\\phantomjs-2.1.1-windows\\bin\\phantomjs.exe")
運行後發現,出錯:
UserWarning: Selenium support for PhantomJS has been deprecated, please use headless versions of Chrome or Firefox instead
warnings.warn('Selenium support for PhantomJS has been deprecated, please use headless '
意思是 selenium 已經不支持 phantomjs 了,建議用無頭版本的火狐或者谷歌。
具體代碼:
from selenium.webdriver.firefox.options import Options
options = Options()
options.add_argument('-headless')
browser = webdriver.Firefox( executable_path="D:/Python36/geckodriver.exe",firefox_options=options)
與之前的相比,多了無頭的配置。這是 無頭 Firefox 的配置,驅動還是使用 geckodriver。
如果運行後發現錯誤,如下:
selenium.common.exceptions.SessionNotCreatedException: Message: Unable to find a matching set of capabilities
原因是版本問題,可以更新 Firefox 到最新版本。
與之相對,谷歌瀏覽器,則要使用 chromdriver 驅動,選擇版本下載,我下載的目前最新的。
代碼如下
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument('-headless')
browser = webdriver.Chrome( executable_path="D:\\Python36\\chromedriver_win32\\chromedriver.exe",chrome_options=options)
頁面操作
定位元素
獲取 html 中的元素,有以下方法。
- find_element_by_id
- find_element_by_name
- find_element_by_xpath
- find_element_by_link_text
- find_element_by_partial_link_text
- find_eelement_by_tag_name
- find_element_by_class_name
- find_element_by_css_selector
如百度輸入框:
<input type="text" class="s_ipt" name="wd" id="kw" maxlength="100" autocomplete="off">
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument('-headless')
browser = webdriver.Chrome( executable_path="D:\\Python36\\chromedriver_win32\\chromedriver.exe",chrome_options=options)
browser.get(url="http://www.baidu.com")
input = browser.find_element_by_id('kw')
我們可以這樣獲取元素,其他獲取方法如其方法名一般意義,如果想要其對輸入框輸入內容可以使用以下方法:
input.send_keys('selenium')
清空則用:
input.clear()
鼠標動作
在頁面中模擬鼠標的動作,包括單擊,雙擊,拖動等等,要導入ActionChains類。
<input type="submit" value="百度一下" id="su" class="btn self-btn bg s_btn">
這是百度,輸入框旁邊的搜索按鈕。
button = browser.find_element_by_id('su')
鼠標移動到某個元素上,如button:
mouse = ActionChains(browser)
mouse.move_to_element(button).perform()
鼠標單擊:此時鼠標已移動到 button 元素上
mouse.click().perform()
或者不用該類的方法直接用:
button.click()
鼠標雙擊:
mouse.double_click().perform()
鼠標右擊:
mouse.double_click().perform()
鼠標單擊並保持不動:
mouse.click_and_hold().perform()
鼠標拖拽:元素之間
mouse.drag_and_drop(input,button).perform()
嘗試一下模擬用戶登錄,並識別驗證碼,驗證登錄,我選取的是本校的圖書館系統。
用戶名和密碼好搞定,但是驗證碼就沒那麼好搞定了,想到使用 OCR 技術,圖文識別,準備想用 Tesseract 來識別驗證碼,但是識別不出來,後來用了阿里的也不行,最後採用了 百度的api,才成功。
首先獲取驗證碼圖片,可以截取整個頁面,然後再從中截取驗證碼圖片。
from PIL import Image
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
image_name = "temp.png"
browser.get_screenshot_as_file(image_name)
image = Image.open(image_name)
box = (221,265,266,284)
region = image.crop(box)
verify_name = "v.png"
region.save(verify_name)
這樣就可以了,box 是 左上右下,座標,可以用系統畫圖工具,獲取,記住要用無頭的瀏覽器,對其截取驗證碼,不然截取得位置會不對,我猜測可能是打開了瀏覽器窗口但不是全屏,故有所偏差。
然後使用了 百度api ,詳細代碼看百度api 文檔調用就行,登錄進了我的圖書館,並且獲取了其中的信息,具體信息我就不透露了,嘿嘿。
大家可以嘗試下其他網站,挑戰下自己。