安裝javascript
pip3 install seleniumcss
測試是否成功html
from selenium import webdriver browser=webdriver.Chrome() #若是能彈出一個空白的chrome瀏覽器頁面,說明配置成功
瀏覽器對象獲取java
from selenium import webdriver #browser=webdriver.Firefox() browser=webdriver.Chrome() #browser=webdriver.Edge() #browser=webdriver.Safari() print(type(browser)) #返回的是一個WebDriver對象 <class 'selenium.webdriver.chrome.webdriver.WebDriver'>
WebDriver對象的方法和屬性:python
from selenium import webdriver driver=webdriver.Chrome() driver.get('https://www.baidu.com') driver.execute_script("alert('are you sure');") #它基本能夠實現JavaScript的全部功能 PS:可是沒有測出來如何獲取js執行結果
from selenium import webdriver browser=webdriver.Chrome() browser.get('http://selenium-python.readthedocs.io') browser.execute_script('window.open("https://www.baidu.com");') #在標籤頁打開URL browser.execute_script('window.open("https://www.taobao.com");') browser.back() #後退到前一個頁面 browser.set_page_load_timeout(5) browser.forward() #前進到下一個頁面 print(browser.name) print(browser.title) print(browser.current_url) print(browser.current_window_handle) print(browser.get_cookies()) print(type(browser)) # chrome Selenium with Python — Selenium Python Bindings 2 documentation http://selenium-python.readthedocs.io/ CDwindow-243FD31239F20FCC0195DD522A60A0DA [{'domain': '.readthedocs.io', 'expiry': 1530766561, 'httpOnly': False, 'name': '_gid', 'path': '/', 'secure': False, 'value': 'GA1.2.1126774326.1530680157'}, {'domain': '.readthedocs.io', 'expiry': 1593752161, 'httpOnly': False, 'name': '_ga', 'path': '/', 'secure': False, 'value': 'GA1.2.2096958532.1530680157'}, {'domain': '.readthedocs.io', 'expiry': 1530680217, 'httpOnly': False, 'name': '_gat_rtfd', 'path': '/', 'secure': False, 'value': '1'}] <class 'selenium.webdriver.chrome.webdriver.WebDriver'>
頁面截圖web
from selenium import webdriver driver=webdriver.Chrome() driver.get('http://www.python.org') driver.save_screenshot('screenshot.png') #保持頁面截圖到當前路徑 driver.quit()
將頁面滾動到底部:正則表達式
from selenium import webdriver driver=webdriver.Chrome() driver.get('http://www.python.org') #經過DOM中的window對象的scrollTo方法,將窗口位置滾動到指定位置,document.body.scrollHeight返回整個body的高度,因此頁面將滾動到頁面底部 driver.execute_script("window.scrollTo(0,document.body.scrollHeight);")
cookies操做:(PS:這段沒有測試)chrome
from selenium import webdriver driver=webdriver.Chrome() driver.get('https://www.baidu.com') print(driver.get_cookies()) #獲取全部cookies driver.add_cookie({'name':'name','domain':'www.baidu.com','value':'germey'}) #添加cookie print(driver.get_cookies()) driver.delete_all_cookies() print(driver.get_cookies())
元素定位api
class selenium.webdriver.common.by.By
有各類策略來定位頁面中的元素。你可使用最適合你的狀況。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_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
除了上面給出的公共方法以外,還有兩個私有方法可能對頁面對象中的定位器有用。這些是兩個私有方法:find_element和find_elements
(PS:這段也沒有測試,之後用到再測試)
from selenium import webdriver from selenium.webdriver.common.by import By driver=webdriver.Chrome() driver.get('http://selenium-python.readthedocs.io/locating-elements.html#locating-elements') data=driver.find_element(By.CLASS_NAME,'simple') #driver.find_element(By.ID,'IDname') #獲取ID標籤訂位元素 #driver.find_element(By.CSS_SELECTOR,'cssname')#CSS選擇器定位元素 #driver.find_element(By.LINK_TEXT,'linktext') #連接文本定位元素 #driver.find_element(By.PARTIAL_LINK_TEXT,'linktext') #部分連接文件定位元素 #driver.find_element(By.NAME,'name') #屬性名定位元素 #driver.find_element(By.TAG_NAME,'tagname') #標籤名定位元素 print(data.text) #打印元素文本內容
元素對象
from selenium import webdriver from selenium.webdriver.chrome.options import Options opt=Options() opt.add_argument('headless') driver=webdriver.Chrome(chrome_options=opt) driver.get('http://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.remote.webelement') element=driver.find_element_by_id('module-selenium.webdriver.remote.webelement') print(element) print(type(element)) #返回一個webelement對象 <selenium.webdriver.remote.webelement.WebElement (session="dfaee65201abdf5a931306df6e7fe421", element="0.95256057244967-1")> <class 'selenium.webdriver.remote.webelement.WebElement'>
selenium.webdriver.remote.webelement.WebElement爲一個DOM元素,它的方法和屬性包括:
元素存在判斷
# 該方法用來確認元素是否存在,若是存在返回flag=true,不然返回false def isElementExist(driver, element): flag = True try: driver.find_element_by_css_selector(element) return flag except: flag = False return flag # 調用 driver是瀏覽器對象 if isElementExist(driver, "[class='airy-ad-prompt-container']"): print("有") else: print("沒有")
抓取網頁源碼,有了它剩下的就是正則表達式捕獲了
from selenium import webdriver driver=webdriver.Chrome() driver.get('http://www.cnblogs.com/zhangxinqi/') element=driver.find_element_by_id('q') #獲取輸入框元素 element.send_keys('python3之requests') #發送元素 button=driver.find_element_by_id('btnZzk') #獲取搜索按鈕 button.click() #發送搜索動做 data=driver.page_source #這裏返回html源碼 print(driver.current_url) #打印URL print(data) print(type(element)) driver.close()
動做模擬
class selenium.webdriver.common.action_chains.ActionChains(driver)
在上面的實例中咱們針對的是某個節點元素的操做,若是要對沒有特定元素的對象操做如鼠標拖拽、鍵盤按鍵等,這些動做就稱爲動做鏈,selenium使用ActionChains()類來實現鼠標移動,鼠標按鈕操做,按鍵操做和上下文菜單交互,懸停和拖放等
拖拽到指定目標(PS:沒有測試)
element = driver.find_element_by_name("source") target = driver.find_element_by_name("target") from selenium.webdriver import ActionChains action_chains = ActionChains(driver) action_chains.drag_and_drop(element, target).perform()
鼠標操做(PS:沒有測試)
menu = driver.find_element_by_css_selector(".nav") #獲取element對象 hidden_submenu = driver.find_element_by_css_selector(".nav #submenu1") #獲取點擊對象 #建立鼠標對象 actions = ActionChains(driver) #移動鼠標到對象 actions.move_to_element(menu) #點擊對象 actions.click(hidden_submenu) #執行操做 actions.perform()
彈出對話框
class selenium.webdriver.common.alert.Alert(driver)
Alert內置支持處理彈窗對話框,方法:
(PS:沒有測試)
import time from selenium import webdriver from selenium.webdriver.common.alert import Alert driver=webdriver.Chrome() driver.get('https://www.baidu.com') driver.execute_script("alert('肯定');") #彈出窗口 time.sleep(2) print(driver.switch_to.alert.text) #獲取alert文本 alert=Alert(driver).accept() #自動點擊肯定窗口
鍵盤操做
class selenium.webdriver.common.keys.Keys
selenium提供一個keys包來模擬全部的按鍵操做,下面咱們介紹下一些經常使用的按鍵操做:
實現點擊頁面從python的pypi頁面下載selenium源碼包:(PS:沒有測試)
import requests from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.action_chains import ActionChains driver=webdriver.Chrome() driver.get('https://pypi.org/') element=driver.find_element_by_id('search') #獲取輸入框 element.send_keys('selenium') #搜索selenium包 element.send_keys(Keys.ENTER) #按回車鍵 element_a=driver.find_element_by_link_text('selenium') #定位selenium包連接 ActionChains(driver).move_to_element(element_a).click(element_a).perform() #按左鍵點擊連接執行 element_down=driver.find_element_by_link_text('Download files') #定位下載連接 ActionChains(driver).move_to_element(element_down).click(element_down).perform() #按左鍵點擊連接 element_selenium=driver.find_element_by_link_text('selenium-3.13.0.tar.gz') #定位元素selenium下載包連接 data=element_selenium.get_attribute('href') #獲取連接地址 with open('selenium-3.13.0.tar.gz','wb') as f: source=requests.get(data).content #請求下載連接地址獲取二進制包數據 f.write(source) #寫入數據 f.close() driver.quit()
延時等待
目前,大多數Web應用程序都在使用AJAX技術。當瀏覽器加載頁面時,該頁面中的元素可能以不一樣的時間間隔加載。這使定位元素變得困難:若是DOM中還沒有存在元素,則locate函數將引起ElementNotVisibleException異常。使用等待,咱們能夠解決這個問題。等待在執行的操做之間提供了一些鬆弛 - 主要是使用元素定位元素或任何其餘操做。
Selenium Webdriver提供兩種類型的等待 - 隱式和顯式。顯式等待使WebDriver等待某個條件發生,而後再繼續執行。在嘗試查找元素時,隱式等待會使WebDriver輪詢DOM一段時間。
顯示等待:
顯示等待是根據定義的代碼,用於在進一步執行代碼以前等待某個條件發送,它提供了一些便捷方法,能夠編寫在僅須要等待的代碼上,實現方法須要WebDriverWait與ExpectedCondition結合使用:
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_delays_loading") try: element = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "myDynamicElement")) ) finally: driver.quit()
在拋出TimeoutException異常以前將等待10秒或者在10秒內發現了查找的元素。 WebDriverWait 默認狀況下會每500毫秒調用一次ExpectedCondition直到結果成功返回。 ExpectedCondition成功的返回結果是一個布爾類型的true或是不爲null的返回值。中文文檔 https://selenium-python-zh.readthedocs.io/en/latest/getting-started.html#id2
其餘等待條件:
中文文檔 https://selenium-python-zh.readthedocs.io/en/latest/waits.html
摘自 https://www.cnblogs.com/zhangxinqi/p/9259808.html
最後附上一份截圖源碼,改了好一會才完成,原始版,未整理
#!/usr/bin/python3 # 截圖測試 # from selenium import webdriver import unittest import os, sys, time import exescript from PIL import Image # 合併截圖,而且裁剪多餘部分 def image_merge(li_path, img_width, img_height): print("圖片處理") max_width = 0 total_height = 0 # 計算合成後圖片的寬度(以最寬的爲準)和高度 for img_path in li_path: if os.path.exists(img_path): img = Image.open(img_path) width, height = img.size if width > max_width: max_width = width total_height += height # 產生一張空白圖 new_img = Image.new("RGB", (max_width, total_height), 255) # 合併 x = y = 0 for img_path in li_path: if os.path.exists(img_path): img = Image.open(img_path) width, height = img.size new_img.paste(img, (x, y)) y += height # 裁剪多餘 print(new_img.size) new_img.save("data/xq.jpg", "JPEG", quality=95) img1 = Image.open("data/xq.jpg") print("寬度", img1.width) print("圖片寬度", img_width) # 計算白邊 cut = ((img1.width - img_width) / 2) - 100 print("白邊", cut) ok_scr = img1.width - cut img_cut_size = (cut, 0, ok_scr, img_height) img2 = img1.crop(img_cut_size) img2.save("data/xq_cut.jpg", "JPEG", quality=95) # 登陸 current_time = time.strftime("%Y-%m-%d-%H_%M_%S", time.localtime(time.time())) current_time1 = time.strftime("%Y-%m-%d", time.localtime(time.time())) print(current_time) print(current_time1) dpath = "config\chromedriver.exe" options = webdriver.ChromeOptions() options.add_argument( 'user-agent="Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36"' ) options.add_argument("--headless") # options.add_argument("headless") # 靜默瀏覽器 # 設置成中文 # options.add_argument('lang=zh_CN.UTF-8') options.add_argument("en-us") # 谷歌文檔提到須要加上這個屬性來規避bug options.add_argument("--disable-gpu") # 禁止加載全部插件,能夠增長速度。能夠經過about:plugins頁面查看效果 options.add_argument("–disable-plugins") # 配了環境變量第一個參數就能夠省了,否則傳絕對路徑 driver = webdriver.Chrome(executable_path=dpath, chrome_options=options) # driver = webdriver.Chrome(executable_path=dpath) url = "https://www.amazon.com/dp/B01L1F1OV6" # 設定屏幕寬 和 高 w_width = 1920 w_height = 1080 driver.set_window_size(w_width, w_height) driver.get(url) # 必須打印圖片路徑HTMLTestRunner才能捕獲而且生成路徑,\image\**\\**.png 是獲取路徑的條件,必須這樣的目錄 # 設置存儲圖片路徑,測試結果圖片能夠按照天天進行區分 # 經過if進行斷言判斷 # driver.get("https://baidu.com/") # # 新建立路徑「.」表示當前整個.py文件的路徑所在的位置,「\\」路徑分割符,其中的一個是「\」表示轉義字符 # pic_path = ".\\result\\image\\" + current_time1 + "\\" + current_time + ".png" # print(pic_path) # time.sleep(5) # print(driver.title) # 截取當前url頁面的圖片,並將截取的圖片保存在指定的路徑下面(pic_path),注:如下兩種方法均可以 # driver.save_screenshot(pic_path) # 能夠注入,可是不必定能夠返回 time.sleep(5) # exejs = exescript.ExeJs(driver) # js_th ='return document.getElementsByClassName("a-section a-spacing-extra-large bucket")[0].clientHeight.toString()' # exejs.exeWrap(js_th) th = driver.execute_script("return document.title;") print(th) # 滾動到指定位置 print("滾動到指定位置") js = 'window.location.hash="aplus"' driver.execute_script(js) # 不容許這樣使用符號類名 # ts1 = driver.find_element_by_class_name("a-section.a-spacing-extra-large.bucket") li_img = [] # 定義截圖保存路徑 try: dw = driver.find_element_by_id("dpx-aplus-3p-product-description_feature_div") # print("定位1", dw.size) # print("定位1", dw.location) # 可行 dw1_height = dw.location["y"] # print("定位1", dw.location_once_scrolled_into_view) xq = driver.find_element_by_css_selector( "[class='a-section a-spacing-extra-large bucket']" ) # print("定位2", xq.size) xq_width = xq.size["width"] xq_height = xq.size["height"] all_height = 0 all_height = xq_height driver.save_screenshot("data/sc_1.png") li_img.append("data/sc_1.png") # 獲取瀏覽器可視區域高度 th_see_height = driver.execute_script("return window.innerHeight;") print("可視高度", th_see_height) # 詳情自己尺寸 xq_ok = driver.find_element_by_css_selector("[class='aplus-v2 desktop celwidget']") # print("定位2", xq.size) xq_ok_width = xq_ok.size["width"] print("展現高度", xq_ok_width) # 若是詳情高度大於設定屏幕高度,就須要二次滾動,甚至屢次滾動 num = 2 while all_height >= th_see_height: print("滾動到指定位置") th = 0 th = dw1_height + th_see_height js = "window.scroll(0," + str(th) + ")" driver.execute_script(js) t_path = "" t_path = "data/sc_" + str(num) + ".png" driver.save_screenshot(t_path) li_img.append(t_path) all_height = all_height - th_see_height if all_height <= th_see_height: break else: num += 1 print("截圖次數", num) print("截圖完成,數據以下") print("路徑", li_img) print("尺寸寬", xq_width) print("尺寸高", xq_height) image_merge(li_img, xq_ok_width, xq_height) except Exception as result: print("檢測出異常{}".format(result)) time.sleep(1) driver.close()