<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
selenium 是一套完整的web應用程式測試系統,包含了測試的錄製(selenium IDE),編寫及執行(Selenium Remote Control)和測試的並行處理(Selenium Grid)。Selenium的核心Selenium Core基於JsUnit,完全由JavaScript編寫,因此可以用於任何支援JavaScript的瀏覽器上。
selenium可以模擬真實瀏覽器,自動化測試工具,支援多種瀏覽器,爬蟲中主要用來解決JavaScript渲染問題。
用python寫爬蟲的時候,主要用的是selenium的Webdriver,我們可以通過下面的方式先看看Selenium.Webdriver支援哪些瀏覽器
from selenium import webdrive help(webdriver)
執行結果如下,從結果中我們也可以看出基本山支援了常見的所有瀏覽器:
NAME: selenium.webdriver
PACKAGE CONTENTS:
VERSION: 3.14.1
PhantomJS是一個而基於WebKit的伺服器端JavaScript API,支援Web而不需要瀏覽器支援,其快速、原生支援各種Web標準:Dom處理,CSS選擇器,JSON等等。
PhantomJS可以用用於頁面自動化、網路監測、網頁截圖,以及無介面測試。
當selenium升級到3.0之後,對不同的瀏覽器驅動進行了規範。如果想使用selenium驅動不同的瀏覽器,必須單獨下載並設定不同的瀏覽器驅動。
各瀏覽器下載地址:
注:webdriver需要和對應的瀏覽器版本以及selenium版本對應。
檢視驅動和瀏覽器版本的對映關係:
按照chrome版本對應的driver,直接按照瀏覽器版本去找對應的driver(只對應大版本就行)
下載之後,解壓到任意目錄(路徑不要有中文)。
瀏覽器驅動檔案,(win環境下載解壓後得到的.exe檔案)需要放到與python.exe同級目錄中方能使用。或者設定電腦環境變數
可以手動建立一個存放瀏覽器驅動的目錄,如: C:driver , 將下載的瀏覽器驅動檔案(例如:chromedriver、geckodriver)丟到該目錄下。
我的電腦-->屬性-->系統設定-->高階-->環境變數-->系統變數-->Path,將“C:driver”目錄新增到Path的值中。
上面我們知道了selenium支援很多的瀏覽器,但是如果想要宣告並呼叫瀏覽器則需要:
這裡只寫了兩個例子,當然了其他的支援的瀏覽器都可以通過這種方式呼叫
from selenium import webdriver browser = webdriver.Chrome() # browser = webdriver.Firefox()
Headless Chrome 是 Chrome 瀏覽器的無介面形態,可以在不開啟瀏覽器的前提下,使用所有 Chrome 支援的特性執行你的程式。相比於現代瀏覽器,Headless Chrome 更加方便測試 web 應用,獲得網站的截圖,做爬蟲抓取資訊等。相比於較早的 PhantomJS,SlimerJS 等,Headless Chrome 則更加貼近瀏覽器環境。
Headless Chrome 對Chrome版本要求:官方檔案中介紹,mac和linux環境要求chrome版本是59+,而windows版本的chrome要求是60+,同時chromedriver要求2.30+版本。
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 from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.keys import Keys chrome_options = webdriver.ChromeOptions() # 使用headless無介面瀏覽器模式 chrome_options.add_argument('--headless') //增加無介面選項 chrome_options.add_argument('--disable-gpu') //如果不加這個選項,有時定位會出現問題 # 啟動瀏覽器,獲取網頁原始碼 browser = webdriver.Chrome(chrome_options=chrome_options) mainUrl = "https://www.taobao.com/" browser.get(mainUrl) print(f"browser text = {browser.page_source}") browser.quit()
下面程式碼執行後,會自動開啟Chrome瀏覽器,並登陸百度列印百度首頁的原始碼,然後關閉瀏覽器
from selenium import webdriver browser = webdriver.Chrome() browser.get("http://www.baidu.com") print(browser.page_source) browser.close()
browser.get(<a href="http://www.taobao.com/" rel="external nofollow" rel="external nofollow" target="_blank">http://www.taobao.com</a>) input_first = browser.find_element_by_id("q") input_second = browser.find_element_by_css_selector("#q") input_third = browser.find_element_by_xpath('//*[@id="q"]') print(input_first) print(input_second) print(input_third) browser.close()
這裡我們通過三種不同的方式去獲取響應的元素,第一種是通過id的方式,第二個中是CSS選擇器,第三種是xpath選擇器,結果都是相同的。
結果如下:
常用的查詢元素方法:
舉例:
通過xpath定位,xpath定位有N種寫法,這裡列幾個常用寫法:
dr.find_element_by_xpath("//*[@id='kw']") dr.find_element_by_xpath("//*[@name='wd']") dr.find_element_by_xpath("//input[@class='s_ipt']") dr.find_element_by_xpath("/html/body/form/span/input") dr.find_element_by_xpath("//span[@class='soutu-btn']/input") dr.find_element_by_xpath("//form[@id='form']/span/input") dr.find_element_by_xpath("//input[@id='kw' and @name='wd']")
通過css定位,css定位有N種寫法,這裡列幾個常用寫法:
dr.find_element_by_css_selector("#kw") dr.find_element_by_css_selector("[name=wd]") dr.find_element_by_css_selector(".s_ipt") dr.find_element_by_css_selector("html > body > form > span > input") dr.find_element_by_css_selector("span.soutu-btn> input#kw") dr.find_element_by_css_selector("form#form > span > input")
xpath的使用方法
1. 第一種方法:通過絕對路徑做定位(相信大家不會使用這種方式)
By.xpath(「html/body/div/form/input」)
2. 第二種方法:通過相對路徑做定位,兩個斜槓代表相對路徑
By.xpath(「//input//div」)
3. 第三種方法:通過元素索引定位
By.xpath(「//input[4]」)
4. 第四種方法:使用xpath+節點屬性定位(結合第2、第3中方法可以使用)
By.xpath(「//input[@id='kw1']」) By.xpath(「//input[@type='name' and @name='kw1']」)
5. 第五種方法:使用部分屬性值匹配(最強大的方法)
By.xpath(「//input[start-with(@id,'nice')]」) By.xpath(「//input[ends-with(@id,'很漂亮')]」) By.xpath(「//input[contains(@id,'那麼美')]」)
6. 第六種方法:使用前集中方法的組合
By.xpath(「//input[@id='kw1']//input[start-with(@id,'nice']/div[1]/form[3])
下面這種方式是比較通用的一種方式:這裡需要記住By模組所以需要匯入。
from selenium import webdriver from selenium.webdriver.common.by import By browser = webdriver.Chrome() browser.get("http://www.taobao.com") input_first = browser.find_element(By.ID,"q") print(input_first) browser.close()
當然這種方法和上述的方式是通用的,browser.find_element(By.ID,"q")這裡By.ID中的ID可以替換為其他幾個
多個元素find_elements,單個元素是find_element,其他使用上沒什麼區別,通過其中的一個例子演示:
browser.get(<a href="http://www.taobao.com/" rel="external nofollow" rel="external nofollow" target="_blank">http://www.taobao.com</a>) lis = browser.find_elements_by_css_selector('.service-bd li') print(lis) browser.close()
這樣獲得就是一個列表
當然上面的方式也是可以通過匯入from selenium.webdriver.common.by import By 這種方式實現
lis = browser.find_elements(By.CSS_SELECTOR,'.service-bd li')
同樣的在單個元素中查詢的方法在多個元素查詢中同樣存在:
一般來說,webdriver 中比較常用的操作物件的方法有下面幾個:
要想呼叫鍵盤按鍵操作需要引入 keys 包:
from selenium.webdriver.common.keys import Keys
通過 send_keys()呼叫按鍵:
send_keys(Keys.TAB) # TAB send_keys(Keys.ENTER) # 回車 send_keys(Keys.CONTROL,'a') # ctrl+a 全選輸入框內容 send_keys(Keys.CONTROL,'x') # ctrl+x 剪下輸入框內容 import time browser.get(http://www.taobao.com) input_str = browser.find_element_by_id('q') input_str.send_keys("ipad") time.sleep(1) input_str.clear() input_str.send_keys("MakBook pro") button = browser.find_element_by_class_name('btn-search') button.click()
執行的結果可以看出程式會自動開啟Chrome瀏覽器並開啟淘寶輸入ipad,然後刪除,重新輸入MakBook pro,並點選搜尋。
滑鼠事件一般包括滑鼠右鍵、雙擊、拖動、移動滑鼠到某個元素上等等。需要引入ActionChains類。引入方法:
from selenium.webdriver.common.action_chains import ActionChains
ActionChains 常用方法:
滑鼠雙擊範例:
qqq =driver.find_element_by_xpath("xxx") #定位到要雙擊的元素 ActionChains(driver).double_click(qqq).perform() #對定位到的元素執行滑鼠雙擊操作
滑鼠拖放範例:
from selenium.webdriver import ActionChains url = "http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable" browser.get(url) browser.switch_to.frame('iframeResult') source = browser.find_element_by_css_selector('#draggable') target = browser.find_element_by_css_selector('#droppable') actions = ActionChains(browser) actions.drag_and_drop(source, target) actions.perform()
更多操作參考:
http://selenium-python.readthedocs.io/api.html
這是一個非常有用的方法,這裡就可以直接呼叫js方法來實現一些操作,下面的例子是通過登入知乎然後通過js翻到頁面底部,並彈框提示
browser.get(<a href="http://www.zhihu.com/explore" rel="external nofollow" target="_blank">http://www.zhihu.com/explore</a>) browser.execute_script('window.scrollTo(0, document.body.scrollHeight)') browser.execute_script('alert("To Bottom")')
url = 'https://www.zhihu.com/explore' browser.get(url) logo = browser.find_element_by_id('zh-top-link-logo') print(logo) print(logo.get_attribute('class'))
url = 'https://www.zhihu.com/explore' browser.get(url) input = browser.find_element_by_class_name('zu-top-add-question') print(input.text)
url = 'https://www.zhihu.com/explore' browser.get(url) input = browser.find_element_by_class_name('zu-top-add-question') print(input.id) print(input.location) print(input.tag_name) print(input.size)
在很多網頁中都是有Frame標籤,所以我們爬取資料的時候就涉及到切入到frame中以及切出來的問題,通過下面的例子演示
這裡常用的是switch_to.from()和switch_to.parent_frame()
import time from selenium import webdriver from selenium.common.exceptions import NoSuchElementException browser = webdriver.Chrome() url = 'http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable' browser.get(url) browser.switch_to.frame('iframeResult') source = browser.find_element_by_css_selector('#draggable') print(source) try: logo = browser.find_element_by_class_name('logo') except NoSuchElementException: print('NO LOGO') browser.switch_to.parent_frame() logo = browser.find_element_by_class_name('logo') print(logo) print(logo.text)
當使用了隱式等待執行測試的時候,如果 WebDriver沒有在 DOM中找到元素,將繼續等待,超出設定時間後則丟擲找不到元素的異常。
換句話說,當查詢元素或元素並沒有立即出現的時候,隱式等待將等待一段時間再查詢 DOM,預設的時間是0
到了一定的時間發現元素還沒有載入,則繼續等待我們指定的時間,如果超過了我們指定的時間還沒有載入就會丟擲異常,如果沒有需要等待的時候就已經載入完畢就會立即執行
browser.implicitly_wait(10) browser.get('https://www.zhihu.com/explore') input = browser.find_element_by_class_name('zu-top-add-question') print(input)
指定一個等待條件,並且指定一個最長等待時間,會在這個時間內進行判斷是否滿足等待條件。
如果成立就會立即返回,如果不成立,就會一直等待,直到等待你指定的最長等待時間,如果還是不滿足,就會丟擲異常,如果滿足了就會正常返回。
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 browser = webdriver.Chrome() browser.get('https://www.taobao.com/') wait = WebDriverWait(browser, 10) input = wait.until(EC.presence_of_element_located((By.ID, 'q'))) button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '.btn-search'))) print(input, button)
上述的例子中的條件:EC.presence_of_element_located()是確認元素是否已經出現了。EC.element_to_be_clickable()是確認元素是否是可點選的
範例:部落格園標題判斷
# coding: utf-8 from selenium import webdriver from selenium.webdriver.support import expected_conditions as EC driver = webdriver.Firefox() driver.get("http://www.cnblogs.com/101718qiong/") title = EC.title_is(u"Silence&QH - 部落格園") # 判斷title完全等於 print title(driver) title1 = EC.title_contains("Silence&QH") # 判斷title包含 print title1(driver) r1 = EC.title_is(u"Silence&QH - 部落格園")(driver) # 另外寫法 r2 = EC.title_contains("Silence&QH")(driver) print r1 print r2
更多操作參考:
http://selenium-python.readthedocs.io/api.html
瀏覽器最大化、最小化
browser.maximize_window() # 將瀏覽器最大化顯示 browser.minimize_window() # 將瀏覽器最小化顯示
瀏覽器設定視窗大小
browser.set_window_size(480, 800) # 設定瀏覽器寬480、高800顯示
瀏覽器前進後退
import time from selenium import webdriver browser = webdriver.Chrome() browser.get('https://www.baidu.com/') browser.get('https://www.taobao.com/') browser.get('https://www.python.org/') browser.back() time.sleep(1) browser.forward() browser.close()
browser.get('https://www.zhihu.com/explore') print(browser.get_cookies()) browser.add_cookie({'name': 'name', 'domain': 'www.zhihu.com', 'value': 'zhaofan'}) print(browser.get_cookies()) browser.delete_all_cookies() print(browser.get_cookies())
通過執行js命令實現新開索引標籤window.open(),不同的索引標籤是存在列表裡browser.window_handles。
通過browser.window_handles[0]就可以操作第一個索引標籤,current_window_handle:獲得當前視窗控制程式碼
import time browser.get('https://www.baidu.com') browser.execute_script('window.open()') print(browser.window_handles) browser.switch_to.window(browser.window_handles[1]) browser.get('https://www.taobao.com') time.sleep(1) browser.switch_to.window(browser.window_handles[0]) browser.get('https://python.org')
這裡的異常比較複雜,官網的參考地址:
http://selenium-python.readthedocs.io/api.html
這裡只進行簡單的演示,查詢一個不存在的元素
from selenium import webdriver from selenium.common.exceptions import TimeoutException, NoSuchElementException browser = webdriver.Chrome() try: browser.get('https://www.baidu.com') except TimeoutException: print('Time Out') try: browser.find_element_by_id('hello') except NoSuchElementException: print('No Element') finally: browser.close()
在WebDriver中處理JavaScript所生成的alert、confirm以及prompt十分簡單,具體做法是使用 switch_to.alert 方法定位到 alert/confirm/prompt,然後使用text/accept/dismiss/ send_keys等方法進行操作。
方法
範例演示
from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains import time driver = webdriver.Chrome("F:ChromeChromeDriverchromedriver") driver.implicitly_wait(10) driver.get('http://www.baidu.com') # 滑鼠懸停至「設定」連結 link = driver.find_element_by_link_text('設定') ActionChains(driver).move_to_element(link).perform() # 開啟搜尋設定 driver.find_element_by_link_text("搜尋設定").click() #在此處設定等待2s否則可能報錯 time.sleep(2) # 儲存設定 driver.find_element_by_class_name("prefpanelgo").click() time.sleep(2) # 接受警告框 driver.switch_to.alert.accept() driver.quit()
匯入選擇下拉框Select類,使用該類處理下拉框操作。
from selenium.webdriver.support.select import Select
Select類的方法:
有時我們會碰到下拉框,WebDriver提供了Select類來處理下拉框。 如百度搜尋設定的下拉框。
from selenium import webdriver from selenium.webdriver.support.select import Select from time import sleep driver = webdriver.Chrome("F:ChromeChromeDriverchromedriver") driver.implicitly_wait(10) driver.get('http://www.baidu.com') #1.滑鼠懸停至「設定」連結 driver.find_element_by_link_text('設定').click() sleep(1) #2.開啟搜尋設定 driver.find_element_by_link_text("搜尋設定").click() sleep(2) #3.搜尋結果顯示條數 sel = driver.find_element_by_xpath("//select[@id='nr']") Select(sel).select_by_value('50') # 顯示50條 sleep(3) driver.quit()
對於通過input標籤實現的上傳功能,可以將其看作是一個輸入框,即通過send_keys()指定本地檔案路徑的方式實現檔案上傳。
通過send_keys()方法來實現檔案上傳:
from selenium import webdriver import os driver = webdriver.Firefox() file_path = 'file:///' + os.path.abspath('upfile.html') driver.get(file_path) # 定位上傳按鈕,新增本地檔案 driver.find_element_by_name("file").send_keys('D:\upload_file.txt') driver.quit()
自動化用例是由程式去執行的,因此有時候列印的錯誤資訊並不十分明確。如果在指令碼執行出錯的時候能對當前視窗截圖儲存,那麼通過圖片就可以非常直觀地看出出錯的原因。WebDriver提供了截圖函數get_screenshot_as_file()來擷取當前視窗。
截圖方法:
get_screenshot_as_file(self, filename) 用於擷取當前視窗,並把圖片儲存到本地
from selenium import webdriver from time import sleep driver =webdriver.Firefox(executable_path ="F:GeckoDrivergeckodriver") driver.get('http://www.baidu.com') driver.find_element_by_id('kw').send_keys('selenium') driver.find_element_by_id('su').click() sleep(2) #1.擷取當前視窗,並指定截圖圖片的儲存位置 driver.get_screenshot_as_file("D:\baidu_img.jpg") driver.quit()
在前面的例子中我們一直使用quit()方法,其含義為退出相關的驅動程式和關閉所有視窗。除此之外,WebDriver還提供了close()方法,用來關閉當前視窗。例多視窗的處理,在用例執行的過程中開啟了多個視窗,我們想要關閉其中的某個視窗,這時就要用到close()方法進行關閉了。
現在不少大網站有對selenium採取了監測機制。比如正常情況下我們用瀏覽器存取淘寶等網站的 window.navigator.webdriver的值為
undefined。而使用selenium存取則該值為true。那麼如何解決這個問題呢?
只需要設定Chromedriver的啟動引數即可解決問題。在啟動Chromedriver之前,為Chrome開啟實驗性功能引數excludeSwitches
,它的值為['enable-automation']
,完整程式碼如下:
from selenium.webdriver import Chrome from selenium.webdriver import ChromeOptions option = ChromeOptions() option.add_experimental_option('excludeSwitches', ['enable-automation']) driver = Chrome(options=option)
自動登陸CSDN
import time import numpy as np from numpy import random from selenium import webdriver from selenium.webdriver import ActionChains from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC def ease_out_expo(x): if x == 1: return 1 else: return 1 - pow(2, -10 * x) def get_tracks(distance, seconds, ease_func): tracks = [0] offsets = [0] for t in np.arange(0.0, seconds+0.1, 0.1): ease = globals()[ease_func] offset = round(ease(t / seconds) * distance) tracks.append(offset - offsets[-1]) offsets.append(offset) return offsets, tracks def drag_and_drop(browser, offset): # 定位滾軸元素 WebDriverWait(browser, 20).until( EC.visibility_of_element_located((By.XPATH, "//*[@class='nc_iconfont btn_slide']")) ) knob = browser.find_element_by_xpath("//*[@class='nc_iconfont btn_slide']") offsets, tracks = get_tracks(offset, 0.2, 'ease_out_expo') ActionChains(browser).click_and_hold(knob).perform() for x in tracks: ActionChains(browser).move_by_offset(x, 0).perform() # 放開 ActionChains(browser).pause(random.randint(6, 14) / 10).release().perform() chrome_options = webdriver.ChromeOptions() chrome_options.add_argument("--start-maximized") browser = webdriver.Chrome(chrome_options=chrome_options) browser.get('http://www.baidu.com') browser.find_element_by_id('kw').send_keys('CSDN') browser.find_element_by_id('su').click() WebDriverWait(browser, 20).until( EC.visibility_of_element_located((By.PARTIAL_LINK_TEXT, "-專業IT技術社群")) ) browser.find_element_by_partial_link_text('-專業IT技術社群').click() browser.switch_to.window(browser.window_handles[1]) # 移動控制程式碼 time.sleep(1) browser.find_element_by_partial_link_text('登入').click() browser.find_element_by_link_text('賬號密碼登入').click() browser.find_element_by_id('all').send_keys('yangbobin') browser.find_element_by_name('pwd').send_keys('pass-word') browser.find_element_by_css_selector("button[data-type='account']").click() time.sleep(5) # 等待滑動模組和其他JS檔案載入完畢! while True: # 定義滑鼠拖放動作 drag_and_drop(browser, 261) # 等待JS認證執行,如果不等待容易報錯 time.sleep(2) # 檢視是否認證成功,獲取text值 WebDriverWait(browser, 20).until( EC.visibility_of_element_located((By.LINK_TEXT, "重新整理")) ) browser.find_element_by_link_text('重新整理').click()
自動登陸163郵箱
首先,是163.的登陸為iframe
browser.switch_to_frame('x-URS-iframe')
到此這篇關於python爬蟲之selenium模組的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45